English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Implement the interface PlatformTransactionManager in Spring Boot transaction management.
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-When using JDBC dependencies, the framework will automatically default inject DataSourceTransactionManager. Therefore, we do not need any additional configuration to use the @Transactional annotation for transaction usage.
JDBC transaction manager
In the Service, methods annotated with @Transactional will support transactions. If the annotation is on the class, all methods in the class will support transactions by default.
Multiple transaction managers
First: you can implement the TransactionManagementConfigurer interface, and the return value of the method inside is the default transaction manager.
Second: you can set the value on the specific execution method.
If there are multiple PlatformTransactionManager instances in the Spring container and no default value is specified by implementing the interface TransactionManagementConfigurer, when we use the annotation @Transactional on a method, we must specify the value. If not specified, an exception will be thrown.
//@EnableTransactionManagement // Enables annotation-based transaction management, equivalent to <tx:annotation> in XML configuration files.-driven /> @SpringBootApplication public class ProfiledemoApplication implements TransactionManagementConfigurer { @Resource(name="txManager2} private PlatformTransactionManager txManager2; // Manually create a transaction manager1 the datasource framework will be automatically injected //In the Spring container, manually annotated @Bean will be loaded first, and the framework will not instantiate other PlatformTransactionManager implementation classes. @Bean(name = "txManager1} public PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } // Create a transaction manager2 @Bean(name = "txManager2} public PlatformTransactionManager txManager2(EntityManagerFactory factory) { return new JpaTransactionManager(factory); } // Implement the TransactionManagementConfigurer interface method, whose return value represents the default transaction manager to use when there are multiple transaction managers @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return txManager2; } public static void main(String[] args) { SpringApplication.run(ProfiledemoApplication.class, args); } }
specific implementation
@Component public class DevSendMessage implements SendMessage { // to specifically 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: By using the isolation attribute setting, for example:
@Transactional(isolation = Isolation.DEFAULT)
Propagation behavior
The propagation behavior of a transaction refers to the fact that if a transaction context already exists before the current transaction begins, there are several options to specify the execution behavior of a transactional method.
We can see that the org.springframework.transaction.annotation.Propagation enumeration class defines6an enumeration value representing the 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 exists, join the transaction; if no transaction exists, create a new transaction. Default value.
SUPPORTS: If a transaction exists, join the transaction; if no transaction exists, continue to run in non-transactional mode.
MANDATORY: If a transaction exists, join the transaction; if no transaction exists, throw an exception. (Forced into the transaction)
REQUIRES_NEW: Create a new transaction, and if a transaction exists, suspend the current transaction. (Commonly used for logging, even if the transaction rolls back, this transaction will still execute and record error information)
NOT_SUPPORTED: Run in non-transactional mode, and if a transaction exists, suspend the current transaction.
NEVER: Run in non-transactional mode, and if a transaction exists, throw an exception.
NESTED: If a transaction exists currently, run a nested transaction as the current transaction; if no transaction exists, this value is equivalent to REQUIRED.
Specify the method: By using the propagation attribute to set, for example:
@Transactional(propagation = Propagation.REQUIRED)
Cases where the transaction does not rollback
Only rollback when a RuntimeException that is not caught occurs
catch the exception thrown, both insertions will succeed
@Override @Transactional public void insertandinsert(Staff staff) { staffDao.insert(staff); try { int i = 1 / 0; } e.printStackTrace(); } staffDao.insert(staff); }
Add the statement TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); in the catch statement of the method in the service layer to manually rollback and not insert data
@Override @Transactional public void insertandinsert(Staff staff) throws Exception { try { staffDao.insert(staff); int i=1/0; staffDao.insert(staff); } TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }
That's all for this article. I hope it will be helpful to everyone's learning and also hope everyone will support the Yelling Tutorial more.
Statement: The content of this article is from the network, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report violations, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)