Updates
  • Starting New Weekday Batch for Full Stack Java Development on 27 September 2025 @ 03:00 PM to 06:00 PM
  • Starting New Weekday Batch for MERN Stack Development on 29 September 2025 @ 04:00 PM to 06:00 PM

Transaction Management

Transaction is the process of performing multiple database operations as one Atomic unit with All-Nothing Criteria.
When all the database operations in the unit are successful then Transaction is successful and should be commited.
When any one database operation in the unit is failed then Transaction is failed and should be rolled back.
When you implement transactions properly in your application, It gaurantees ACID Properties.
  A - Atomicity
  C - Consistency
  I - Isolation
  D - Durability

Types of Transactions

Local Transactions
Distributed Transactions

Local Transactions

When a Single Database is participating in the Transactional Operations then it is called as Local Transactions.

Ex:
Transfer the funds from one account to another account where two accounts are in same bank or same database.

Distributed Transactions

When two or more Databases are participating in the Transactional Operations then it is called as Distributed Transactions.

Ex:
Transfer the funds from one account to another account where two accounts are in different banks or different databases.

Note: JDBC Supports only Local Transactions and doesn’t support Distributed Transactions.

JDBC Transaction Management:

Specifying the Transactional Boundaries.

Connection con=null;
try{
con=...;
con.setAutoCommit(false); // Transaction Begin
op1;
op2;
op3;
con.commit(); // Transaction End
}catch(Exception e){
if(con!=null){
con.rollback();
// Transaction End
}
}

When multiple transactions are running concurrently then you may get some transactional concurrency problems.

  Dirty Read Problem
  Repeatable Read Problem
  Phantom Read Problem

You need to specify the Transactional Isolation Levels to solve these transactional concurrency problems.
There are 4 Transactional Isolation Levels which are defined as Constants in Connection interface as follows.
  TRANSACTION_READ_UNCOMMITTED 1
  TRANSACTION_READ_COMMITTED 2
  TRANSACTION_REPEATABLE_READ 4
  TRANSACTION_SERIALIZABLE 8

Use the following method to specify the required Transactional Isolation Level

  con.setTransactionIsolation(2);
  con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

DB Work for Program

1. Create the following table
create table myaccounts(
accno int primary key,
atype char(2),
bal double
);

2. Insert some Sample Records
insert into myaccounts values(101,'SA',25000);
insert into myaccounts values(102,'SA',5000);

            
package com.jtcindia.jdbc;
import java.sql.*;

class InvalidAccountNumberException extends RuntimeException {
   int accno;
   InvalidAccountNumberException() {}
   InvalidAccountNumberException(int accno) {
      this.accno = accno;
   }
   public String toString() {
      return "Accno : " + accno + " is Not Found";
   }
}
class InsufficientFundsException extends RuntimeException {
   InsufficientFundsException() {}
   public String toString() {
      return "Sufficient Funds are Not Available";
   }
}
class AccountService {
   void fundsTransfer(int saccno, int daccno, double amt) throws SQLException {
      Connection con = null;
      PreparedStatement ps1 = null;
      PreparedStatement ps2 = null;
      ResultSet rs = null;
      try {
    	  Class.forName("com.mysql.cj.jdbc.Driver");
  		String url = "jdbc:mysql://localhost:3306/tutorial?autoReconnect=true&useSSL=false";
  		con = DriverManager.getConnection(url, "root", "root");
         con.setAutoCommit(false); // Tx Begin
         String SQL1 = "select bal from myaccounts where accno=?";
         String SQL2 = "update myaccounts set bal=? where accno=?";
         ps1 = con.prepareStatement(SQL1);
         ps2 = con.prepareStatement(SQL2);
         // Deposit
         ps1.setInt(1, daccno); // 102
         rs = ps1.executeQuery(); //OP1-Select
         if (rs.next()) {
            double bal = rs.getInt(1);
            bal = bal + amt;
            ps2.setDouble(1, bal);
            ps2.setInt(2, daccno);
            ps2.executeUpdate(); // OP2-Update
         } else {
            throw new InvalidAccountNumberException();
         }
         // Withdraw
         ps1.setInt(1, saccno); // 101
         rs = ps1.executeQuery(); //OP3-Select
         if (rs.next()) {
            double bal = rs.getInt(1);
            if (bal >= amt) {
               bal = bal - amt;
               ps2.setDouble(1, bal);
               ps2.setInt(2, saccno);
               ps2.executeUpdate(); // OP4-Update
            } else {
               throw new InsufficientFundsException();
            }
         } else {
            throw new InvalidAccountNumberException();
         }
         con.commit(); // End of Tx
         System.out.println("----Done-----");
      } catch (Exception ex) {
         ex.printStackTrace();
         try {
            con.rollback(); // End of Tx
         } catch (SQLException e) {
            e.printStackTrace();
         }
      } finally {
         rs.close();
         ps1.close();
         con.close();
      }
   }
}
public class Transaction_Management {
   public static void main(String[] args) throws SQLException {
      AccountService as = new AccountService();
      as.fundsTransfer(101, 102, 5000);
   }
}