Spring transaction management
Spring transactions are divided into two types: programmatic transactions and declarative transactions.
1. Programming services
Program the transaction, obtain the TransactionTemplate object, and then control the transaction submission and rollback
DAO
@Component public interface DemoDao { @Insert("insert into demo values(1,2000)") void insert(); }
Service
@Component public class DemoService { @Autowired DemoDao demoDao; // Get TransactionTemplate object @Autowired TransactionTemplate transactionTemplate; // Programming transaction public void inset2() throws Exception { // Transaction processing transactionTemplate.execute(new TransactionCallback<Boolean>() { @Override public Boolean doInTransaction(TransactionStatus status) { demoDao.insert(); // You can roll back here. If you want to commit, do not write this section status.setRollbackOnly(); return false; } }); } }
Class configured
@Configuration @ComponentScan("cn.zl") @MapperScan("cn.zl.dao") @EnableTransactionManagement @PropertySource("data.yml") public class Config { // Inject data source object @Bean public DataSource dataSource(DatabaseParam databaseParam){ PooledDataSource pooledDataSource = new PooledDataSource(); pooledDataSource.setUsername(databaseParam.getUsername()); pooledDataSource.setPassword(databaseParam.getPassword()); pooledDataSource.setDriver(databaseParam.getDriver()); pooledDataSource.setUrl(databaseParam.getUrl()); return pooledDataSource; } // Create an sql object @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource ds) throws IOException { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(ds); // Configure data sources sqlSessionFactoryBean.setTypeAliasesPackage("cn.zl.model"); // Set entity class alias return sqlSessionFactoryBean; } //Configure transaction manager @Bean public DataSourceTransactionManager transactionManager(DataSource ds){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(ds); return transactionManager; } // Inject transaction management objects to receive transactions @Bean public TransactionTemplate transactionTemplate(DataSourceTransactionManager dataSourceTransactionManager){ TransactionTemplate transactionTemplate = new TransactionTemplate(dataSourceTransactionManager); return transactionTemplate; } }
test
public class Main { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); DemoService bean2 = applicationContext.getBean(DemoService.class); // deal with affairs bean2.inset2(); } }
2. Declarative transactions
Programming business mainly depends on
@Component public class DemoService { @Autowired DemoDao demoDao; @Transactional(rollbackFor = Exception.class) public void inset() throws Exception { demoDao.insert(); // Exceptions thrown here can be rolled back throw new Exception(); } }
3. Take a look at the @ Transactional annotation
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Transactional { @AliasFor("transactionManager") String value() default ""; // These two values have the same effect. Set the manager for the transaction @AliasFor("value") String transactionManager() default ""; // Set propagation behavior of transactions Propagation propagation() default Propagation.REQUIRED; // Set the isolation level of the transaction Isolation isolation() default Isolation.DEFAULT; // Set the timeout for the transaction. int timeout() default TransactionDefinition.TIMEOUT_DEFAULT; // Set the current transaction as read-only. boolean readOnly() default false; // This attribute is used to set the array of exception classes that need to be rolled back. When the method throws an exception in the specified exception array, the transaction is rolled back. Class<? extends Throwable>[] rollbackFor() default {}; // This attribute is used to set the array of exception class names that need to be rolled back. When an exception in the array of specified exception names is thrown in the method, the transaction is rolled back String[] rollbackForClassName() default {}; // This attribute is used to set the array of exception names that do not need to be rolled back. When an exception in the specified exception array is thrown in the method, transaction rollback will not be performed. Class<? extends Throwable>[] noRollbackFor() default {}; // This attribute is used to set the exception class name array that does not need to be rolled back. When an exception in the specified exception name array is thrown in the method, transaction rollback will not be performed String[] noRollbackForClassName() default {}; }
4. Communication of affairs
Suppose method A calls method B now, and the transaction of method A will affect method B. So this is the propagation behavior of transactions. There are four situations.
- Method A has transactions, and method B also has transactions
- Method A has no transactions and method B has transactions
- Method A has transactions and method B has no transactions
- Method A has no transactions, and method B has no transactions
4.1 PROPAGATION_REQUIRED default
When A calls B, if method A has A transaction, B will join the transaction of method A for execution. If method A has no transaction, method B starts A new transaction.
If we call method a and method B separately, a transaction will be created. If the method B is called in the method A, the method B is added to the method A.
4.2 PROPAGATION_SUPPORTS
It supports external transactions and does not create transactions by itself. If there is external, it is supported and does not run in a non transactional manner.
Simply calling method B will not create A transaction and will be executed in A non transaction manner. Here, method A must be REQUIRED. When method A calls method B, method B supports the current transaction.
4.3 PROPAGATION_MANDATORY
Mandatory external transactions. If the external transaction already exists, it is supported. If not, an exception will be thrown.
If method B is called directly from outside, an exception illegaltransactionstateexception will be thrown: no existing transaction found for transaction marked with promotion 'mandatory'. The method B is called in the method A, and the method B supports the transaction of the method A.
4.4 PROPAGATION_REQUIRES_NEW (request a new transaction)
Using PROPAGATION_REQUIRES_NEW, you need to use JTA transaction manager as the transaction manager
It does not support external transactions. If there is no external transaction, start a transaction. If there is an external transaction, suspend it.
When methodB is called separately, a transaction will be started. When methodA calls methodB, it will suspend the transaction of methodA and open a new transaction for methodB. Of course, method B transaction commit has nothing to do with rolling back the transaction with method a. The two transactions are irrelevant.
4.5 PROPAGATION_NOT_SUPPORTED (not supported)
It does not support any transaction. It will not create a transaction itself. It is always executed in a non transactional manner, and any transaction will be suspended.
When methodB is called externally, methodB will not create any transactions and run in a non transactional manner. When methodA calls methodB, the transaction of methodA will be suspended, and methodB will still run in a non transactional manner.
4.6 PROPAGATION_NEVER (never use transactions)
Never use transactions. Throw exceptions if there are external transactions.
4.7 PROPAGATION_NESTED
If an active transaction exists, a sub transaction will be opened and nested in an external transaction. If there is no active transaction, it will be executed according to the REQUIRED attribute.
JDBC version 3.0 is required
A nested transaction is a sub transaction, not a new transaction. The commit and rollback of external transactions will affect the commit and rollback of sub transactions.