This is a concurrent money transfer system built in Go to handle money tarnsfers between users with built in protections.
- Creation of Users/accounts with starting balance.
- Make Transfer to other users
- Atomic Money Tranfers
- Prevention of overdrafts
- Concurrently safe account operations
Go 1.20 or higher
- Clone the repository
- Run
go mod tidyto download all dependencies - Run the application with
go run cmd/main.go
- Create Account
URL: /account/create
Method: POST
Request Body
{
"user_id": "kowshik",
"balance": 25.50
}
Response Body
{"status":"account created","user_id":"kora"}
- Get Balance
URL: /account/balance?user_id=kowshik
Method: GET
Response Body
{"balance":25.50}
- Transfer
URL: /transfer
Method: POST
Request Body
{
"from_user_id" : "kowshik",
"to_user_id" : "ram",
"amount": 15.45
}
Response Body
{"status":"transfer successful"}
-
Grained Lock on Individual Accounts during Transfer
- Instead of using a global lock on all transfers , we lock the two accounts involved in a transfer.
- This improves concurrency cuz we can allow multiple transfers happening at the same time.
-
Implemented Ordered Locking to prevent deadlock
- When two users send money to each other at same time, it may lock in different orders causing deadlock. So to avoid that we compare user_ids and do a ordered lock.
-
RWMutex during Concurrent Reads
Get account balancewould be used in different places including exposing in a API and also during transfer to fetch the current balance. So implemented read-only lock so that multiple goroutines can read them concurrently.
Account Create
curl --location 'http://localhost:8080/account/create' \
--header 'Content-Type: application/json' \
--data '{
"user_id" : "kora",
"balance": 50
}'
Get account Balance
curl --location 'http://localhost:8080/account/balance?user_id=kora' \
--data ''
Transfer money
curl --location 'http://localhost:8080/transfer' \
--header 'Content-Type: application/json' \
--data '{
"from_user_id" : "kora",
"to_user_id" : "kowshik",
"amount": 50
}'