Combining multiple transactional method in one transaction

Method with @Transactional commits the transaction when it returns. If you want to combine multiple transactional method in one transaction, propagation policy is the solution.

Solution A

  • To make a parent method with @Transactional
  • To delete @Transactional at sub methods to combine the transaction

Solution B

  • To make a parent method with @Transactional (default propagation level is “MANDATORY”)
  • To change sub method’s propagation level to “SUPPORTS” (which means “Support a current transaction, execute non-transactionally if none exists.”) or “MANDATORY” (which means “Support a current transaction, throw an exception if none exists.”)
  • Be warned that the parent method accesses sub method through spring context (to access proxy object)

Example – parent method

@Repository
public class TestMultiDao {
	@Autowired
	private TestSubDao subDao;

	@Transactional
	public void insertMulti() {
		subDao.insertData("1", "111");
		subDao.insertData("2", "222");
	}
}

Example – sub method

@Repository
public class TestSubDao {
	private JdbcTemplate jdbcTemplate;

	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	@Transactional(propagation=Propagation.SUPPORTS)
	public void insertData(String col1, String col2) {
		this.jdbcTemplate.update("INSERT INTO TRANSACTION_TEST(COL1, COL2) VALUES(?, ?)", col1, col2);
	}
}

When running above code, the following log is shown

DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Creating new transaction with name [test.dao.TestMultiDao.insertMulti]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ”
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Acquired Connection […] for JDBC transaction
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Switching JDBC Connection […] to manual commit
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Participating in existing transaction
DEBUG: org.springframework.jdbc.core.JdbcTemplate – Executing prepared SQL update
DEBUG: org.springframework.jdbc.core.JdbcTemplate – Executing prepared SQL statement [INSERT INTO TRANSACTION_TEST(COL1, COL2) VALUES(?, ?)]
DEBUG: org.springframework.jdbc.core.JdbcTemplate – SQL update affected 1 rows
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Participating in existing transaction
DEBUG: org.springframework.jdbc.core.JdbcTemplate – Executing prepared SQL update
DEBUG: org.springframework.jdbc.core.JdbcTemplate – Executing prepared SQL statement [INSERT INTO TRANSACTION_TEST(COL1, COL2) VALUES(?, ?)]
DEBUG: org.springframework.jdbc.core.JdbcTemplate – SQL update affected 1 rows
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Initiating transaction commit
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Committing JDBC transaction on Connection […]
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager – Releasing JDBC Connection […] after transaction
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils – Returning JDBC Connection to DataSource
  1. A transaction object is created
  2. A jdbc connection is acquired and set as manual commit
  3. Executing the first sql with the connection
  4. Executing the second sql with the same connection
  5. Committing the transaction
  6. Releasing the connection
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.