Transactions 101: Essential Knowledge for Every IT Professional

Learn what transactions are in IT systems and why they matter. Understand ACID properties, see real-world banking examples, and discover how transactions ensure data consistency and reliability in modern applications through practical SQL and Java examples.

What is a transaction ? Why is it something that’s spoken most about in any IT conversations or a big metric that’s used across all the places? Lets get into understanding it

A transaction is a single logical unit of work that the system treats as “all-or-nothing.

In real systems, one business action usually involves multiple technical steps. A classic example is transferring money from one bank account to another. Even though the user sees it as one action, the system typically performs multiple updates behind the scenes.

Why transactions are so important

In banking (and many other domains), systems often follow a ledger approach:

  • An account table stores the current balance.
  • A ledger table stores the history of movements (who paid whom, how much, when, and why).

For a transfer to be correct, both account balances and the ledger entry must be updated together.

Transaction: What it is and why it matters in every IT system

A transaction is a single logical unit of work that the system treats as “all-or-nothing.”

In real systems, one business action usually involves multiple technical steps. A classic example is transferring money from one bank account to another. Even though the user sees it as one action, the system typically performs multiple updates behind the scenes.

Why transactions are so important

In banking (and many other domains), systems often follow a ledger approach:

  • An account table stores the current balance.
  • A ledger table stores the history of movements (who paid whom, how much, when, and why).

For a transfer to be correct, both account balances and the ledger entry must be updated together.

Transaction explained with a transfer example

Assume a user transfers ₹100 from Account A to Account B. Internally, the system may do:

  1. Debit Account A by ₹100
  2. Credit Account B by ₹100
  3. Insert a row into the ledger for the transfer

If any one step fails, you can end up with money “lost”, double-counted, or untraceable.

Scenario 1: Debit succeeded, credit failed

  • Account A debited
  • Account B not credited
  • Ledger entry may or may not exist
    Result: User B panics; system state is inconsistent.

Scenario 2: Credit succeeded, ledger insert failed

  • Account A debited ✅
  • Account B credited ✅
  • Ledger insert failed ❌
    Result: Money moved, but there’s no trace → “suspense/unaccounted” money.

Scenario 3: Debit succeeded, credit succeeded, ledger not updated

Same issue as Scenario 2, but even more dangerous at scale: reconciliation breaks.
In all these scenarios, if one operation fails, the entire set of operations must be rolled back.

That’s exactly what transactions guarantee.

ACID properties of transactions

Transactions provide reliability using the classic ACID properties:

  • Atomicity: all steps happen, or none happen
  • Consistency: rules remain true (e.g., “no negative balance” if that’s a rule)
  • Isolation: concurrent operations don’t corrupt each other
  • Durability: once committed, the result persists even after crashes/power loss

Because of these guarantees, most transactional data is stored in relational (SQL) databases where the primary purpose of the system is to enforce these constraints.

Database Transaction Example

This is one transaction , either all updates should happen or nothing should happen.To ensure this happens , while executing this transaction , database will start a transaction and end a transaction . For explicit transaction handling we should use the BEGIN and END statements

BEGIN /*-- transaction start
UPDATE account act
SET act.bal = act.bal-100
where acct.number = 123;

UPDATE account act
SET act.bal = act.bal+100
where acct.number = 234; 

insert into ledger(from_account,to_account ,type ,amount) 
value (123,234,"cash transfer",100);
END; --transaction end 


In case of long transactions , we have option of check points and we can roll back to the said check point, this ensure logical conclusion of transaction.

For this reason , most of the applications have these type of logics written inside the database as a procedure / function / package and allow an application to call.

Plain Java (JDBC) Transaction

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.sql.*;

public class TransferServiceJdbc {

  private final DataSource dataSource;

  public TransferServiceJdbc(DataSource dataSource) {
    this.dataSource = dataSource;
  }

  public void transfer(long fromAcct, long toAcct, BigDecimal amount) throws SQLException {
    String debitSql =
        "UPDATE account SET bal = bal - ? " +
        "WHERE number = ? AND bal >= ?"; // prevents negative balance

    String creditSql =

        "UPDATE account SET bal = bal + ? " +
        "WHERE number = ?";

    String ledgerSql =
        "INSERT INTO ledger(from_account, to_account, type, amount) " +
        "VALUES (?, ?, ?, ?)";

    try (Connection con = dataSource.getConnection()) {
      con.setAutoCommit(false);                 // BEGIN
      con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

      try (
          PreparedStatement debit = con.prepareStatement(debitSql);
          PreparedStatement credit = con.prepareStatement(creditSql);
          PreparedStatement ledger = con.prepareStatement(ledgerSql)
      ) {
        // 1) debit
        debit.setBigDecimal(1, amount);
        debit.setLong(2, fromAcct);
        debit.setBigDecimal(3, amount);
        int debited = debit.executeUpdate();
        if (debited != 1) {
          throw new IllegalStateException("Debit failed: account not found or insufficient funds");
        }

        // 2) credit
        credit.setBigDecimal(1, amount);
        credit.setLong(2, toAcct);
        int credited = credit.executeUpdate();
        if (credited != 1) {
          throw new IllegalStateException("Credit failed: destination account not found");
        }

        // 3) ledger insert
        ledger.setLong(1, fromAcct);
        ledger.setLong(2, toAcct);
        ledger.setString(3, "cash transfer");
        ledger.setBigDecimal(4, amount);
        ledger.executeUpdate();

        con.commit();                           // END / COMMIT
      } catch (Exception e) {
        con.rollback();                         // ROLLBACK on any failure
        throw e;
      }
    }
  }
}

Transactions are the backbone of reliable and consistent data management in modern IT systems. Whether you’re building banking systems, e-commerce platforms, or any application that manages critical data, understanding transactions is fundamental.

The key takeaway is simple: transactions ensure that either all operations succeed together, or they all fail and roll back. This “all-or-nothing” guarantee powered by ACID properties prevents data inconsistencies, financial discrepancies, and system instability.

In practice, you have multiple options:

  • Use a relational database with built-in transaction support and let the database handle the complexity.
  • Implement explicit transaction control through SQL BEGIN/END statements or stored procedures for complex operations.
  • Write application-level transaction logic in Java, Python, or your preferred language when necessary.

Regardless of the approach, always remember: a single point of failure in a multi-step operation can compromise your entire system’s integrity. By leveraging transactions effectively, you can build robust systems that users can trust.

As you design your next system, make transactions a core part of your architecture from day one. It’s far easier to implement them correctly upfront than to fix data corruption issues later.

srnyapathi
srnyapathi
Articles: 41