Here I will tell you about the transaction management in Spring framework. A transaction is a logical unit of work that contains one or more statements with the following features:
- A transaction is an atomic unit.
- The effects of all the statements in a transaction can be either all committed or all rolled back.
Transaction management is an important part of enterprise applications to ensure data integrity and consistency.
The concept of transactions can be described as ACID(Atomicity, Consistency, Isolation, Durability) property:
Atomicity requires that each transaction is “all or nothing” which means either the sequence of a transaction is successful or unsuccessful. If one part of a transaction fails then entire transaction fails.
The database value should be consistent from state to state while any data written to the database for any combination of constraints, cascade, triggers etc.
Each transaction must be executed in isolation in concurrent environment to prevent data corruption.
Once a transaction has been committed, the results of this transaction have to be made permanent even in the event of power loss, crashes, or errors.
For example, consider a banking system. When a bank customer transfers money from an account A to an account B, the transaction can consist of three separate operations:
- Decrement the amount from account A
- Increment the amount into account B
- Record the transaction in the transaction journal
If all three above statements can be performed to maintain the accounts in proper balance, the effects of the transaction can be applied to the persistent storage such as database or file. However, if a problem such as insufficient funds, invalid account number, or a hardware failure prevents one or two of the statements in the transaction from completing, the entire transaction must be rolled back so that the balance of all accounts(account A and account B) is correct.
Committing a transaction means making permanent the changes performed by the statements within the transaction.
Rolling back means undoing any changes to data that have been performed by statements within an uncommitted transaction.
A distributed transaction is a transaction that includes one or more statements that update data on two or more distinct nodes of a distributed persistent storage.
A two-phase commit mechanism guarantees that all persistant storage servers participating in a distributed transaction either all commit or all undo the statements in the transaction. A two-phase commit mechanism also protects implicit DML operations performed by integrity constraints, remote procedure calls, and triggers.
Transaction in Spring Framework
In Spring there are two choices for transactions Global and Local.
Global transaction has the following characteristics:
- enables to work with multiple resources such as relational databases and message queues
- distributed transaction
- requires two phase commit
- very complex to configure for properly recovery
Example: in a bank transfer amount from one account to another account in two steps
1. debit amount from one account using database connection
2. creadit amount to another account using webservice or jms
Local transaction has the following characteristics:
- resource specific so works with single resource
- easier to use but has limitation because cannot be used across multiple transactional resources
Example: in a bank transfer amount from one account to another account within a single database using single database connection
Abstraction in Spring Transaction
It is a notion of transaction strategy which specifies the following things:
Each transaction is executed separately.
All code which are in a transaction scope will run only within that transaction. For example, code can continue running in the existing transaction (the common case); or the existing transaction can be suspended and a new transaction created.
How long this transaction runs before timing out and being rolled back automatically by the underlying transaction infrastructure.
A read-only transaction can be used when your code reads but does not modify data. Read-only transactions can be a useful optimization in some cases, such as when you are using Hibernate.
Types of Spring Transaction Management
Spring supports two types of transaction management: Programmatic and Declarative.
Programmatic Transaction Management
You have manage the transaction with the help of programming and it gives you flexibility to customize but difficult to maintain.
Please look at this tutorial for Programmatic Transaction Management in Spring
Declarative Transaction Management
This option has the least impact on application code and happens using Spring AOP. You need to use only annotations or XML based configuration to manage the transactions.
Please look at this tutorial for Declarative Transaction Management in Spring
Propagation Behavior in Spring Transaction
Following are the behaviors for Spring Transaction:
- the same transaction, if already exists, will be used in the current bean method execution context
- if the transaction does not exist already then a new transaction will be created
- if multiple methods configured with REQUIRED behaviour then they will share the same transaction
- this behaviour means a new transaction will always be created irrespective of whether a transaction exists or not
- each transaction runs independently
- commit or rollback happens in the same transaction with savepoints
- an opened transaction must exist otherwise container will throw an Exception
- an opened transaction must not exist otherwise container will throw an Exception
- if an opened transaction exists it will be paused because it is out of scope of any transaction
- if an opened transaction already exists then it will be executed within that transaction
- if any transaction does not exist then it will be executed in a non-transactional manner
Thanks for your reading.