Skip to content

vivek075/Documentation-Spring-Transaction

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 

Repository files navigation

Documentation-Spring-Transaction

Gives high level details around Transactions.

In Spring Boot, the @Transactional annotation is used to manage transactions in a declarative manner. This allows developers to define the scope of a transaction and control its behavior regarding isolation and propagation without manually handling the transaction lifecycle.

Understanding @Transactional

Basic Usage

The @Transactional annotation can be applied to methods or classes to indicate that the method or all methods within the class should be executed within a transaction context.

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

    @Transactional
    public void performDatabaseOperations() {
        // Perform various database operations here
    }
}

Propagation Levels

Propagation defines how transactions interact with each other. Here are the different propagation levels:

REQUIRED (default): Joins an existing transaction if one exists; otherwise, starts a new one.

REQUIRES_NEW: Suspends the current transaction and starts a new one.

MANDATORY: Joins an existing transaction; throws an exception if no current transaction exists.

NESTED: Executes within a nested transaction if a current transaction exists.

NOT_SUPPORTED: Executes outside of a transaction context; suspends the current transaction if one exists.

NEVER: Executes outside of a transaction context; throws an exception if a current transaction exists.

SUPPORTS: Joins an existing transaction if one exists; executes non-transactionally if none exists.

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void newTransactionMethod() {
    // This will run in a new transaction, suspending the current one if it exists
}

Isolation Levels

Isolation levels define the visibility of changes made in one transaction to other concurrent transactions. Spring supports the following isolation levels:

DEFAULT: Uses the default isolation level of the underlying database.

READ_UNCOMMITTED: Allows dirty reads, non-repeatable reads, and phantom reads.

READ_COMMITTED: Prevents dirty reads; non-repeatable reads and phantom reads can occur.

REPEATABLE_READ: Prevents dirty reads and non-repeatable reads; phantom reads can occur.

SERIALIZABLE: Prevents dirty reads, non-repeatable reads, and phantom reads.

@Transactional(isolation = Isolation.SERIALIZABLE)
public void serializableTransactionMethod() {
    // This method will run with the highest isolation level, ensuring full isolation
}

How Transactions Work Internally When the @Transactional annotation is used, Spring creates a proxy for the annotated method or class. This proxy intercepts method calls and manages the transaction lifecycle, including:

Opening a transaction before the method execution. Committing the transaction if the method completes successfully. Rolling back the transaction if an exception occurs (configurable). Internally, Spring uses a PlatformTransactionManager (like DataSourceTransactionManager for JDBC) to manage transaction boundaries.

Difficult Issues in Transactions

Deadlocks: Occur when two or more transactions are waiting for each other to release resources. Proper handling of lock management and using appropriate isolation levels can mitigate this.

Lost Updates: Occur when multiple transactions read the same data and then update it, with one transaction's update overwriting the other's.

Dirty Reads: One transaction reads uncommitted changes made by another transaction, which might get rolled back later.

Non-repeatable Reads: Data read twice in the same transaction yields different results due to updates by other transactions.

Phantom Reads: New records added by another transaction become visible within the scope of a transaction when it performs a query again.

Nested Transactions: Handling nested transactions can be complex, especially ensuring that inner transactions commit or roll back properly in relation to outer transactions.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OuterService {

    @Autowired
    private InnerService innerService;

    @Transactional
    public void outerMethod() {
        // Perform some database operation
        innerService.innerMethod();
        // Perform another database operation
    }
}

@Service
public class InnerService {

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void innerMethod() {
        // This will run in a new transaction
        // Perform database operation
    }
}

In this example, outerMethod starts a transaction, and innerMethod runs within a new transaction because of the REQUIRES_NEW propagation. If innerMethod fails, its transaction will be rolled back, but outerMethod's transaction will not be affected.

About

Give high level details around Transactions.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors