package com.example.spring.bank.tx; import java.math.BigDecimal; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.example.spring.bank.Account; import com.example.spring.bank.AccountManager; /** * This class decorates a given AccountManager by adding transaction boundaries. * * @author kamal * */ public class TxAccountManager implements AccountManager { private AccountManager accountManager; public void setAccountManager(AccountManager accountManager) { this.accountManager = accountManager; } private TransactionTemplate txTemplate; public void setTxManager(DataSourceTransactionManager txManager) { txTemplate = new TransactionTemplate(txManager); } @Override public Account create() { return txTemplate.execute(new TransactionCallback() { @Override public Account doInTransaction(TransactionStatus arg0) { return accountManager.create(); } }); } @Override public Account find(int accountNumber) { return accountManager.find(accountNumber); } @Override public Account deposit(int accountNumber, BigDecimal amount) { return txTemplate.execute(new TransactionCallback() { @Override public Account doInTransaction(TransactionStatus arg0) { return accountManager.deposit(accountNumber, amount); } }); } @Override public Account withdraw(int accountNumber, BigDecimal amount) { return txTemplate.execute(new TransactionCallback() { @Override public Account doInTransaction(TransactionStatus arg0) { return accountManager.withdraw(accountNumber, amount); } }); } @Override public void delete(int accountNumber) { txTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { accountManager.delete(accountNumber); } }); } @Override public void chargeForLowBalance(BigDecimal minimumBalance, BigDecimal amount) { txTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { accountManager.chargeForLowBalance(minimumBalance, amount); } }); } @Override public Account transfer(int accountNumber1, int accountNumber2, BigDecimal amount) { return txTemplate.execute(new TransactionCallback() { @Override public Account doInTransaction(TransactionStatus status) { try { return accountManager.transfer(accountNumber1, accountNumber2, amount); } catch (Exception e) { // Some exception occurred. status.setRollbackOnly(); throw e; } } }); } }