Skip to content

RolandSall/2PC-PostgresSQL

Repository files navigation

Two-Phase Commit (2PC) System

This project demonstrates a Two-Phase Commit (2PC) protocol implementation using Node.js and PostgreSQL. The system consists of three Node.js applications:

  1. Coordinator: Orchestrates the 2PC protocol between participant services
  2. User Service: Manages user data and participates in the 2PC protocol
  3. Order Service: Manages order data and participates in the 2PC protocol

Architecture

The system follows a distributed transaction architecture using the Two-Phase Commit protocol:

  • Phase 1 (Prepare): The coordinator asks all participants to prepare for a transaction. Each participant validates the request, executes the transaction without committing, and responds with readiness.
  • Phase 2 (Commit/Rollback): If all participants are ready, the coordinator instructs them to commit. If any participant fails, all are instructed to rollback.

PostgreSQL's native support for 2PC is used through the PREPARE TRANSACTION, COMMIT PREPARED, and ROLLBACK PREPARED commands. The PostgreSQL configuration includes setting max_prepared_transactions=100 to enable support for prepared transactions, which is required for the 2PC protocol.

Prerequisites

  • Docker and Docker Compose

Running the System

Option 1: Using the Automated Setup Script (Recommended)

The project includes a convenience script run.sh that:

  1. Installs all dependencies for the coordinator and services
  2. Starts the PostgreSQL containers using Docker Compose
  3. Starts all three Node.js applications locally in separate terminals
  4. Launches a sample transaction

To use the script:

# Make the script executable (if not already)
chmod +x run.sh

# Run the script
./run.sh

Option 2: Manual Setup

  1. Clone the repository
  2. Start the PostgreSQL containers using Docker Compose:
# If containers were already running, stop and remove them first
docker-compose down

# Start the containers with the updated configuration
docker-compose up -d

Note: If you've previously run the system, make sure to restart the PostgreSQL containers to apply the configuration for prepared transactions.

  1. Install dependencies for each service:
npm install
cd coordinator && npm install && cd ..
cd service1 && npm install && cd ..
cd service2 && npm install && cd ..
  1. Start each service in a separate terminal:
# Terminal 1
cd coordinator && node src/index.js

# Terminal 2
cd service1 && node src/index.js

# Terminal 3
cd service2 && node src/index.js

This setup will:

  • Start two PostgreSQL databases (for User Service and Order Service) in Docker containers
  • Run the three Node.js services (Coordinator, User Service, and Order Service) locally

Configuration

The project uses environment variables for configuration, which are stored in .env files:

Coordinator Service (.env)

PORT=3000
SERVICE1_URL=http://localhost:3001
SERVICE2_URL=http://localhost:3002

User Service (.env)

PORT=3001
PGHOST=localhost
PGUSER=postgres
PGPASSWORD=postgres
PGDATABASE=user_service_db
PGPORT=5432

Order Service (.env)

PORT=3002
PGHOST=localhost
PGUSER=postgres
PGPASSWORD=postgres
PGDATABASE=order_service_db
PGPORT=5433

Testing the System

Using the HTTP File

The project includes a transactions.http file at the root level that contains example requests for testing:

  1. Successful Transaction
  2. Unsuccessful Transaction (with negative quantity)
  3. Get All Transactions
  4. Get Specific Transaction

If you're using VS Code with the REST Client extension or JetBrains IDEs, you can execute these requests directly from the file.

Using curl

You can also test the system by initiating a transaction through the coordinator using curl:

Successful Transaction

curl -X POST http://localhost:3000/transaction \
  -H "Content-Type: application/json" \
  -d '{
    "user": {
      "username": "john_doe",
      "email": "john@example.com"
    },
    "order": {
      "user_id": 1,
      "product_name": "Smartphone",
      "quantity": 1,
      "total_price": 999.99
    }
  }'

Failed Transaction (will trigger rollback)

curl -X POST http://localhost:3000/transaction \
  -H "Content-Type: application/json" \
  -d '{
    "user": {
      "username": "jane_doe",
      "email": "jane@example.com"
    },
    "order": {
      "user_id": 2,
      "product_name": "Laptop",
      "quantity": -1,
      "total_price": 1499.99
    }
  }'

Check Transaction Status

curl http://localhost:3000/transaction/{transactionId}

Replace {transactionId} with the ID returned from the transaction creation request.

API Endpoints

Coordinator Service (port 3000)

  • POST /transaction: Initiates a new transaction
  • GET /transaction/:id: Gets the status of a specific transaction
  • GET /transactions: Lists all transactions

User Service (port 3001)

  • POST /prepare: Prepares a transaction (called by coordinator)
  • POST /commit: Commits a prepared transaction (called by coordinator)
  • POST /rollback: Rolls back a prepared transaction (called by coordinator)
  • GET /transaction/:id: Gets the status of a specific transaction

Order Service (port 3002)

  • POST /prepare: Prepares a transaction (called by coordinator)
  • POST /commit: Commits a prepared transaction (called by coordinator)
  • POST /rollback: Rolls back a prepared transaction (called by coordinator)
  • GET /transaction/:id: Gets the status of a specific transaction

Implementation Details

PostgreSQL 2PC Support

The system leverages PostgreSQL's built-in support for two-phase commit:

  1. BEGIN: Starts a transaction
  2. PREPARE TRANSACTION 'name': Prepares the transaction for commit
  3. COMMIT PREPARED 'name': Commits a prepared transaction
  4. ROLLBACK PREPARED 'name': Rolls back a prepared transaction

Error Handling

The system handles various error scenarios:

  • Prepare phase failures
  • Commit phase failures
  • Rollback failures
  • Network issues between services

In case of failures, the system attempts to maintain consistency by rolling back all prepared transactions.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published