10 posts
Transactional annotation
This annotation is supported in Spring Framework 2.0 and higher for transaction management. Can be used at method level or class level, and applies the transaction to all public methods of that method or class.
How @Transactional works
When executing the Spring boot application, classes such as TransactionAutoConfiguration required to create a proxy are automatically activated at . Therefore, sending a client request enables transaction processing for methods to which @Transactional is applied.
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(TransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
public static class EnableTransactionManagementConfiguration {
@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
public static class JdkDynamicAutoProxyConfiguration {}
@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
public static class CglibAutoProxyConfiguration {}
}
}
As you can see from the code above, in order to enable ProxyConfiguration configuration with TransactionAutoConfiguration, you must have PlatformTransactionManager() as a prerequisite according to @ConditionalOnClass. generally
spring-jdbc
me
spring-data-jpa
If you include dependencies such as DataSourceTransactionManage or JpaTransactionManager, classes such as PlatformTransactionManager are used as implementations. The TransactionManager configured in this way creates a connection object and enables transaction commit or rollback.
Once TransactionManager is selected, the transaction management function is activated through the ProxyConfiguration class where @EnableTransactionManagement is declared. Two ProxyConfiguration classes are proposed: JDK Dynamic Proxy and CGLIB. The difference is that JDK Dynamic Proxy creates a proxy object based on an interface, while CGLIB creates a subclass of the original object through bytecode manipulation.
Spring uses the AOP framework to create proxies and perform additional actions by intercepting specific method calls.
Properties of @Transactional
- propagation
- REQUIRED, REQUIRES_NEW, NESTED, SUPPORTS, MANDATORY, NOT_SUPPORTED, NEVER
- isolation (isolation level)
- READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
- readonly (readonly or not)
- timeout
### Consider this when using it! 1. The method for which you want to apply a transaction must be declared public. This is because a proxy object must provide an externally accessible interface. If the method is declared private or protected, the method cannot be accessed when the proxy object is created, so transaction management using the @Transactional annotation is not possible. 2. Conflicts with other AOP features must be considered. For example, if @Secured is used to check whether a user has permission, but @Transactional is performed first, the permission check becomes meaningless. To prevent this, you can use @Order to determine the application order or adjust the application scope. Additionally, you can force the proxy to target a class by setting the @Transactional proxyTargetClass property to true. However, there is a disadvantage that performance may decrease. 3. Let's use it in the Service layer. By using @Transactional in the service layer, multiple database operations can be processed atomically. In addition, in Spring, according to the single responsibility principle, it takes on roles unrelated to business logic in the database layer to improve code maintenance and scalability. Then why does JPA use @Transactional for SimpleJpaRepository? SimpleJpaRepository provided by Spring Data JPA is slightly different from typical repository implementations. SimpleJpaRepository utilizes the functions provided by JPA to process some business logic. For example, when you save an entity using the save() method, you perform an action by determining whether it is new or has already been saved. And even if a mixed transaction occurs, @Transactional in the service layer generally takes priority. 4. Let’s consider exceptions. Transactions are rolled back on RuntimeException and Error, but not on Checked exceptions. Checked exceptions refer to predictable errors, and you can enable rollback processing by adding the rollbackFor property to @Transactional as shown below.
@Transactional(rollbackFor={Exception.class})
5. Java and Kotlin When a Transaction Checked exception occurs In Java, checked exceptions are handled with a try-catch and throw method without being rolled back, but in Kotlin, you can see the transaction being rolled back. However, you can also use @Throws to prevent rollback like in Java. Therefore, developers must consider various exception handling methods depending on which language they use with Spring and how they configure custom exceptions. 6. Transactions and DeadLock In fact, the DeadLock issue occurred, so it was one of the parts I looked at most carefully while refactoring. It is very important how the methods set in the service layer occupy resources in the database.
@Transactional Knowing and using it correctly Spring Transaction Management: @Transactional In-Depth
Comments
No comments yet. Be the first!