Spring Transaction Management | Spring boot


Today we will learn about spring transaction management with the help of spring boot. Let’s learn some basics of spring transaction management.

Spring_Transaction_Management

Actually Transaction defines ACID properties.

  1. Atomicity – All success or none.
  2. Consistency – Database constraints should not be violated.
  3. Isolation – One transaction should not affect another one.
  4. Durability – It should in Database after commit.

Two-way we can manage Spring Transaction Management:

    1. Programmatic transaction management
    2. Declarative transaction management

Programmatic transaction management:

Actually in Programmatic transaction management we generally write code for transaction management like

  1. Creating Transaction reference
  2. Begin transaction
  3. Commit or rollback of the transaction

Example:

Transaction transactionObj = entityManager.getTransaction()
try {
transactionObj.begin();
// Custom business logic
transactionObj .commit();
} catch(Exception e) {
transactionObj.rollback();
//Exception handle
}

Declarative transaction management:

In Declarative transaction management we do not write any extra line code for initiating transaction, Here we generally use annotation based or XML based approach.

If we are using annotation based then we use @Transactional annotation and if we use XML based approach we need to configure DataSourceTransactionManager or any other transaction manager in XML as bean.

Annotation Based Example:

@Transactional(readOnly=true, propagation = Propagation.REQUIRES_NEW)
public Stock findOneString objectId) {
return repository.findOne(objectId);
}

XML Based example:

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:context=”http://www.springframework.org/schema/context” xmlns:tx=”http://www.springframework.org/schema/tx” xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd”>

<bean id=”transactionManagerBean”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource” ref=”dataSource” />
</bean>

</beans>

Great, we have learned ACID properties and different approaches to implement transaction in spring.

@Transactional this is one of the main annotation which is responsible for the declarative transaction management. we will also see the usage of @EnableTransactionManagement.

@Transactional can be used for class or method level.

Consider following example:

@Service(“stockServiceImpl”)
public class stockServiceImpl implements StockService{

@Autowired
private StockRepository stockRepository;

public Stock saveStock(Stock stock) {
Stock st = stockRepository.save(stock);
int a = 100/0; //Exception generated
System.out.println(a);
return st ;
}
}

Here savStock() after saving data in database it throws ArithmeticException. so here there is inconsistency of data in database. That means if any exception occurred then this transaction will be incomplete.

To rectify above transaction issue we have implemented following code:

@Service(“stockServiceImpl”)
public class StockServiceImpl implements StockService{

@Autowired
private StockRepository stockRepository;

@Transactional
public Stock saveStock(Stock stock) {
Stock st= stockRepository.save(stock);
int a = 10/0;
System.out.println(a);
return st;
}
}

As we are using @Transactional annotation with saveStock(). if exception occurred at anywhere in saveStock() entire transaction will get roll backed and here we will not have any record in database.

Attributes of @Transactional annotation:

@Transactional(isolation = Isolation.DEFAULT, propagation=Propagation.REQUIRES_NEW, readOnly=true, noRollbackFor =ArithmeticException.class, timeout = 30000, value=”txManager2″, rollbackFor = { Exception.class }, rollbackForClassName = {“Exception”}, noRollbackForClassName={“Exception”})

Let’s see all properties step by step:

propagation attributes:

  • Propagation.REQUIRED: Support a current transaction, create a new one if none exists.
  • Propagation.REQUIRES_NEW: Always create a new transaction and suspend the current transaction if already exist.
  • Propagation.MANDATORY: Support a current transaction, throw an exception if none exists.
  • Propagation.NESTED: Execute within a nested transaction if a current transaction exists.
  • Propagation.NEVER: Execute non-transactionally, throw an exception if a transaction exists.
  • Propagation.NOT_SUPPORTED: Execute non-transactionally, suspend the current transaction if one exists.
  • Propagation.SUPPORTS: Support a current transaction, execute non-transactionally if none exists.

Propagation.REQUIRED and Propagation.REQUIRES_NEW is frequently used in real-time development.

Default Propagation value is Propagation.REQUIRED

isolation attributes :

  • Isolation.READ_UNCOMMITTED:  It allows dirty reads, non-repeatable reads, and phantom reads.
  • Isolation.READ_COMMITTED: Dirty reads are prevented, allows non-repeatable and phantom reads.
  • Isolation.REPEATABLE_READ: Dirty reads and non-repeatable prevented, phantom reads permitted.
  • Isolation.SERIALIZABLE: Dirty reads, non-repeatable reads, and phantom reads are prevented.

Default isolation value is Isolation.DEFAULT.

rollbackFor attributes:

Here we can have 0, 1 or multiple exception for which we want rollback of transaction.
@Transactional(rollbackFor = {RuntimeException.class})

rollbackForClassName attributes:

Here we can have 0, 1 or multiple exception for which we want rollback of transaction.
@Transactional(rollbackForClassName = {“NullPointerException”})

noRollbackForClassName attributes:

Here we can have 0, 1 or multiple exception for which we don’t want rollback of transaction.
@Transactional(noRollbackForClassName = {“NullPointerException”})

readOnly attributes:

It is used for value can be true or false
@Transactional(readOnly = false)

Posted on:


%d bloggers like this: