In Spring Boot transaction management, implement the self-interface PlatformTransactionManager.
public interface PlatformTransactionManager { org.springframework.transaction.TransactionStatus getTransaction(org.springframework.transaction.TransactionDefinition transactionDefinition) throws org.springframework.transaction.TransactionException; void commit(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException; void rollback(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException;}When we use spring-boot-starter-jdbc dependency, the framework will automatically inject DataSourceTransactionManager by default. So we don't need any additional configuration to use the @Transactional annotation for transaction use.
jdbc transaction manager
In Service, the method annotated by @Transactional will support transactions. If the annotation is on a class, all methods of the entire class support transactions by default.
Multi-transaction manager situation
1: You can implement the TransactionManagementConfigurer interface, and the return value of the method inside is the default transaction manager.
2: You can set the value on the specific execution method
If there are multiple PlatformTransactionManager instances in the Spring container and the interface TransactionManagementConfigurer is not implemented to specify the default value, when we use the annotation @Transactional on the method, we must specify it with value. If it is not specified, an exception will be thrown.
//@EnableTransactionManagement // Turn on annotation transaction management, which is equivalent to <tx:annotation-driven />@SpringBootApplicationpublic class ProfiledemoApplication implements TransactionManagementConfigurer { @Resource(name="txManager2") private PlatformTransactionManager txManager2; // Manually create transaction manager 1 The datasource framework will be automatically injected // In the Spring container, we manually annotate @Bean will be loaded first, and the framework will not re-instrate other PlatformTransactionManager implementation classes. @Bean(name = "txManager1") public PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } // Create TransactionManager 2 @Bean(name = "txManager2") public PlatformTransactionManager txManager2(EntityManagerFactory factory) { return new JpaTransactionManager(factory); } // Implement the interface TransactionManagementConfigurer Method whose return value represents the transaction manager used by default if you have multiple transaction managers @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return txManager2; } public static void main(String[] args) { SpringApplication.run(ProfiledemoApplication.class, args); }}Specific implementation
@Componentpublic class DevSendMessage implements SendMessage { // Use value to specify which transaction manager to use @Transactional(value="txManager1") @Override public void send() { System.out.println(">>>>>>>>>>>>>Dev Send()<<<<<<<<"); send2(); } @Transactional public void send2() { System.out.println(">>>>>>>>>>>>Dev Send2()<<<<<<<<"); }}Isolation level
public enum Isolation { DEFAULT(TransactionDefinition.ISOLATION_DEFAULT), READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED), READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED), REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ), SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE); private final int value; Isolation(int value) { this.value = value; } public int value() { return this.value; }} Specify method: Set by using the isolation property, for example:
@Transactional(isolation = Isolation.DEFAULT)
Communication behavior
The so-called transaction propagation behavior refers to that if a transaction context already exists before the current transaction is started, there are several options that can specify the execution behavior of a transactional method.
We can see that the org.springframework.transaction.annotation.Propagation enumeration class defines 6 enum values that represent propagation behavior:
public enum Propagation { REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), NEVER(TransactionDefinition.PROPAGATION_NEVER), NESTED(TransactionDefinition.PROPAGATION_NESTED); private final int value; Propagation(int value) { this.value = value; } public int value() { return this.value; }}REQUIRED: If a transaction is currently present, join the transaction; if there is currently no transaction, create a new transaction. default value.
SUPPORTS: If a transaction is currently present, join the transaction; if there is currently no transaction, continue running in a non-transactional manner.
MANDATORY: If a transaction is currently present, join the transaction; if there is currently no transaction, an exception is thrown. (Forced to put it into the transaction)
REQUIRES_NEW: Creates a new transaction, and if the transaction currently exists, the current transaction will be suspended. (Printing logs is often used. Even if the previous rollback is rolled back, the transaction will be executed and the error message will be recorded)
NOT_SUPPORTED: Runs in a non-transactional manner. If a transaction currently exists, the current transaction will be suspended.
NEVER: Runs in a non-transactional manner, throws an exception if a transaction currently exists.
NESTED: If a transaction currently exists, a transaction is created to run as a nested transaction of the current transaction; if there is no transaction currently, the value is equivalent to REQUIRED.
Specify method: Set by using the propagation property, for example:
@Transactional(propagation = Propagation.REQUIRED)
Transaction not rollback situation
Roll back only if an uncaught RuntimeException occurs
The exception thrown by catch will be successful when both inserts
@Override @Transactional public void insertandinsert(Staff staff) { staffDao.insert(staff); try { int i = 1 / 0; }catch (Exception e){ e.printStackTrace(); } staffDao.insert(staff); }Added to the catch statement of the service layer method: TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); statement, manual rollback will not insert data
@Override @Transactional public void insertandinsert(Staff staff) throws Exception { try { staffDao.insert(staff); int i=1/0; staffDao.insert(staff); }catch (Exception e){ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.