jeudi 4 octobre 2018

High performance Springboot Banking Application Design

I was trying to do a project involving multi-threading in springboot.

In the Bank Application , I can make operations like doWithdrawal() as synchronizedin order to maintain the integrity of the account , but I am not able to figure out how to do it at particular account level only .

Since users with different account numbers should be able perform withdrawal at same time , with my current code doWithdrawal() will make all operations synchronized irrespective of the account number .

Currently I have very basic functionality below where i have used on withdrawals from one account as a synchronized operation . I want a scenario where different account holders can withdraw from there own account at same time , but while multiple withdraws from the same account at same time , only that process should be synchronous .

So what I am looking here for is how the application should be designed to have such functionality , I am aware we can use @Async for asynchronous operations but not sure how will that fit in the scenario where withdrawal for same account should be synchronous but different should be asynchronous.

Account.java

public class Account {

    int number ;
    float currentBalance ;
    float openingBalance ;
    String accountHolder ;
    String branch ;
    float rateOfInterest ;

    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
    public float getCurrentBalance() {
        return currentBalance;
    }
    public void setCurrentBalance(float currentBalance) {
        this.currentBalance = currentBalance;
    }
    public float getOpeningBalance() {
        return openingBalance;
    }
    public void setOpeningBalance(float openingBalance) {
        this.openingBalance = openingBalance;
    }
    public String getAccountHolder() {
        return accountHolder;
    }
    public void setAccountHolder(String accountHolder) {
        this.accountHolder = accountHolder;
    }
    public String getBranch() {
        return branch;
    }
    public void setBranch(String branch) {
        this.branch = branch;
    }
    public float getRateOfInterest() {
        return rateOfInterest;
    }
    public void setRateOfInterest(float rateOfInterest) {
        this.rateOfInterest = rateOfInterest;
    }


}

App.java

public class App {

    public static void main(String[] args) {

        BankService.openAccount(1001);

        Thread2 t2 = new Thread2();
        Thread3 t3 = new Thread3();
        Thread4 t4 = new Thread4();

        t2.start();
        t3.start();
        t4.start();

    }
}

class Thread2 extends Thread {
    BankService bs = BankService.getInstance();
    public void run(){
        System.out.println("bs instrance is"+bs.hashCode());
        bs.doWithdrawal(200, 1001);
    }
}
class Thread3 extends Thread {
    BankService bs = BankService.getInstance();

    public void run(){
        System.out.println("bs instrance is"+bs.hashCode());

        bs.doWithdrawal(100, 1001);
    }
}
class Thread4 extends Thread {
    BankService bs = BankService.getInstance();
    public void run(){
        System.out.println("bs instrance is"+bs.hashCode());

        bs.doWithdrawal(100, 1001);
    }
}

BankService.java

import java.util.HashMap;
import java.util.Map;



public class BankService {


    private static BankService bankService ;

    private BankService(){

    }

    public static BankService getInstance(){

        if(bankService==null){
            return bankService = new BankService();
        }

        return bankService;
    }


    static Map<Integer,Account> accountMap = new HashMap<Integer, Account>();

    public void doDeposit(float amount,int accountNum){

        Account acc = accountMap.get(accountNum);
        acc.setCurrentBalance(acc.getCurrentBalance()+amount);
        System.out.println("made deposit");
        System.out.println("account :   "+acc.getNumber()+"   "+acc.getCurrentBalance());

    }


    public synchronized void doWithdrawal(float amount,int accountNum){

        Account acc = accountMap.get(accountNum);
        acc.setCurrentBalance(acc.getCurrentBalance()-amount);
        System.out.println("account :   "+acc.getNumber()+"   "+acc.getCurrentBalance());

    }

    public void checkBalance(int accountNumber){

    }

    public static void openAccount(int accnum){

        Account acc = new Account();
        acc.setCurrentBalance(2000);
        acc.setNumber(1001);

        accountMap.put(acc.getNumber(), acc);

        System.out.println("obj is"+accountMap);

    }
}

Aucun commentaire:

Enregistrer un commentaire