Which is the Better Approach?

And why?

  • Readability?
  • Maintainability?
  • Testability?
  • Debugging?
  • Performances?

Transaction Script in Java

(source)

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class BankTransactionExecutor {

    public void executeTransaction(Transaction transaction, Connection conn) throws Exception {
        conn.setAutoCommit(false);
        try {
            Account account = getAccountById(transaction.getAccountId(), conn);
            if ("W".equals(transaction.getCode()) ) {
                if (account.getBalance() >= transaction.getAmount() && transaction.getAmount() > 0) {
                   updateBalance(conn, account, account.getBalance() - transaction.getAmount());
                } else {
                    throw new Exception("Insufficient balance or invalid withdrawal amount.");
                }
            } else if ("D".equals(transaction.getCode())) {
                if (transaction.getAmount() > 0) {
                    throw new Exception("Invalid deposit amount.");
                }
                updateBalance(conn, account, account.getBalance() + transaction.getAmount());
            }
            createTransaction(conn, transaction.getAccountId(), transaction.getAmount(), transaction.getCode());
            conn.commit();
        } catch (Exception e) {
            conn.rollback();
            throw e;
        }
    }

    private void updateBalance(Connection conn, Account account, double newBalance) throws SQLException {
        String sql = "UPDATE account SET balance = ? WHERE id = ?";
        try (PreparedStatement statement = conn.prepareStatement(sql)) {
            statement.setDouble(1, newBalance);
            statement.setInt(2, account.getId());
            statement.executeUpdate();
        }
    }

    private void createTransaction(Connection conn, int accountId, double amount, String code) throws SQLException {
        String sql = "INSERT INTO transaction (account_id, amount, code) VALUES (?, ?, ?)";
        try (PreparedStatement statement = conn.prepareStatement(sql)) {
            statement.setInt(1, accountId);
            statement.setDouble(2, amount);
            statement.setString(3, code);
            statement.executeUpdate();
        }
    }

    private Account getAccountById(int accountId, Connection conn) throws SQLException {
        String sql = "SELECT * FROM account WHERE id = ?";
        try (PreparedStatement statement = conn.prepareStatement(sql)) {
            statement.setInt(1, accountId);
            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    return new Account(resultSet.getInt("id"), resultSet.getDouble("balance"));
                }
            }
        }
        throw new SQLException("Account not found");
    }
}
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class BankTransactionExecutor {

    public void executeTransaction(Transaction transaction, Connection conn) throws Exception {
        conn.setAutoCommit(false);
        try {
            Account account = getAccountById(transaction.getAccountId(), conn);
            if ("W".equals(transaction.getCode()) ) {
                if (account.getBalance() >= transaction.getAmount() && transaction.getAmount() > 0) {
                   updateBalance(conn, account, account.getBalance() - transaction.getAmount());
                } else {
                    throw new Exception("Insufficient balance or invalid withdrawal amount.");
                }
            } else if ("D".equals(transaction.getCode())) {
                if (transaction.getAmount() > 0) {
                    throw new Exception("Invalid deposit amount.");
                }
                updateBalance(conn, account, account.getBalance() + transaction.getAmount());
            }
            createTransaction(conn, transaction.getAccountId(), transaction.getAmount(), transaction.getCode());
            conn.commit();
        } catch (Exception e) {
            conn.rollback();
            throw e;
        }
    }

    private void updateBalance(Connection conn, Account account, double newBalance) throws SQLException {
        String sql = "UPDATE account SET balance = ? WHERE id = ?";
        try (PreparedStatement statement = conn.prepareStatement(sql)) {
            statement.setDouble(1, newBalance);
            statement.setInt(2, account.getId());
            statement.executeUpdate();
        }
    }

    private void createTransaction(Connection conn, int accountId, double amount, String code) throws SQLException {
        String sql = "INSERT INTO transaction (account_id, amount, code) VALUES (?, ?, ?)";
        try (PreparedStatement statement = conn.prepareStatement(sql)) {
            statement.setInt(1, accountId);
            statement.setDouble(2, amount);
            statement.setString(3, code);
            statement.executeUpdate();
        }
    }

    private Account getAccountById(int accountId, Connection conn) throws SQLException {
        String sql = "SELECT * FROM account WHERE id = ?";
        try (PreparedStatement statement = conn.prepareStatement(sql)) {
            statement.setInt(1, accountId);
            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    return new Account(resultSet.getInt("id"), resultSet.getDouble("balance"));
                }
            }
        }
        throw new SQLException("Account not found");
    }
}

Transaction Script in Procedural SQL

(source: me)

do
$$
declare 
    _transaction_id int = $1; -- transaction id parameter
    _transaction record;
    _account record;
begin
    select code, amount, account_id into _transaction 
    from transactions 
    where transaction_id = _transaction_id;

    if _transaction is null then
        raise exception 'Transaction not found';
    end if;
    
    select balance into _account 
    from accounts 
    where account_id = _transaction.account_id;

    if _account is null then
        raise exception 'Account not found';
    end if;

    if _transaction.code = 'W' then
        if _account.balance >= _transaction.amount and _transaction.amout > 0 then
            update accounts 
            set balance = _account.balance - _transaction.amount 
            where account_id = _transaction.account_id;
        else
            raise exception 'Insufficient balance or invalid withdrawal amount.';
        end if;
    elsif _transaction.code = 'D' then
        if _transaction.amount > 0 then
            raise exception 'Invalid deposit amount.';
        else
            update accounts 
            set balance = _account.balance + _transaction.amount 
            where account_id = _transaction.account_id;
        end if;
    end if;

    insert into transactions (account_id, amount, code)
    values (_transaction.account_id, _transaction.amount, _transaction.code);
end;
$$;
do
$$
declare 
    _transaction_id int = $1; -- transaction id parameter
    _transaction record;
    _account record;
begin
    select code, amount, account_id into _transaction 
    from transactions 
    where transaction_id = _transaction_id;

    if _transaction is null then
        raise exception 'Transaction not found';
    end if;
    
    select balance into _account 
    from accounts 
    where account_id = _transaction.account_id;

    if _account is null then
        raise exception 'Account not found';
    end if;

    if _transaction.code = 'W' then
        if _account.balance >= _transaction.amount and _transaction.amout > 0 then
            update accounts 
            set balance = _account.balance - _transaction.amount 
            where account_id = _transaction.account_id;
        else
            raise exception 'Insufficient balance or invalid withdrawal amount.';
        end if;
    elsif _transaction.code = 'D' then
        if _transaction.amount > 0 then
            raise exception 'Invalid deposit amount.';
        else
            update accounts 
            set balance = _account.balance + _transaction.amount 
            where account_id = _transaction.account_id;
        end if;
    end if;

    insert into transactions (account_id, amount, code)
    values (_transaction.account_id, _transaction.amount, _transaction.code);
end;
$$;
To receive notifications about new posts and updates, consider subscribing to my LinkdIn page:
vb-software linkedin

You will receive notifications about new posts on your LinkedIn feed.
Comments