Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Implementing Transactional Fund Transfers in Spring

Notes May 12 2

Data Model Configruation

Define the entity representing a financial account within the system.

package com.example.financial.model;

import java.io.Serializable;

public class BankAccount implements Serializable {
    private Long accountId;
    private String accountHolder;
    private Double availableBalance;

    public BankAccount() {
    }

    public BankAccount(Long accountId, String accountHolder, Double availableBalance) {
        this.accountId = accountId;
        this.accountHolder = accountHolder;
        this.availableBalance = availableBalance;
    }

    // Getters and Setters
    public Long getAccountId() {
        return accountId;
    }

    public void setAccountId(Long accountId) {
        this.accountId = accountId;
    }

    public String getAccountHolder() {
        return accountHolder;
    }

    public void setAccountHolder(String accountHolder) {
        this.accountHolder = accountHolder;
    }

    public Double getAvailableBalance() {
        return availableBalance;
    }

    public void setAvailableBalance(Double availableBalance) {
        this.availableBalance = availableBalance;
    }
}

Data Access Layer (DAO)

Create an interface to hendle balence modifications via JDBC.

package com.example.financial.dao;

public interface AccountRepository {
    int updateAccountBalance(Long accountId, Double amount);
}

Implement the repository using JdbcTemplate to execute the SQL update.

package com.example.financial.dao.impl;

import com.example.financial.dao.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class JdbcAccountRepository implements AccountRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int updateAccountBalance(Long accountId, Double amount) {
        String sqlStatement = "UPDATE bank_accounts SET available_balance = available_balance + ? WHERE account_id = ?";
        return jdbcTemplate.update(sqlStatement, amount, accountId);
    }
}

Business Service Layer

Define the service contract for transferring funds between accounts.

package com.example.financial.service;

public interface TransferService {
    boolean executeTransfer(Long sourceId, Long targetId, Double amount);
}

Implement the business logic to handle the debit and credit operations.

package com.example.financial.service.impl;

import com.example.financial.dao.AccountRepository;
import com.example.financial.service.TransferService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MoneyTransferService implements TransferService {

    @Autowired
    private AccountRepository accountRepository;

    @Override
    public boolean executeTransfer(Long sourceId, Long targetId, Double amount) {
        // Debit the source account
        int debitResult = accountRepository.updateAccountBalance(sourceId, -amount);

        // Credit the target account
        int creditResult = accountRepository.updateAccountBalance(targetId, amount);

        return debitResult > 0 && creditResult > 0;
    }
}

Integration Testing

Verify the functionality by initializing the Spring context and invoking the transfer method.

package com.example.financial.test;

import com.example.financial.service.TransferService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TransactionTestSuite {

    @Test
    public void testTransferExecution() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        TransferService transferService = context.getBean(TransferService.class);

        boolean status = transferService.executeTransfer(1L, 2L, 500.0);
        System.out.println("Operation Status: " + status);
    }
}
Tags: spring

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.