详解:事务注解 @Transactional

发布于:2025-02-27 ⋅ 阅读:(16) ⋅ 点赞:(0)

创作内容丰富的干货文章很费心力,感谢点过此文章的读者,点一个关注鼓励一下作者,激励他分享更多的精彩好文,谢谢大家!


@Transactional Spring Framework 中常用的注解之一,它可以被用于管理事务。通过使用这个注
解,我们可以方便地管理事务,保证数据的一致性和完整性。
Spring 应用中,当我们需要对数据库进行操作时,通常需要使用事务来保证数据的一致性和完整
性。
@Transactional 注解可以被用于类或方法上,用于指定事务的管理方式。当它被用于类上时,它表示
该类中所有的方法都将被包含在同一个事务中。当它被用于方法上时,它表示该方法将被包含在一个新
的事务中。
@Transactional 注解有多个属性,其中最常用的是 propagation isolation
propagation 属性用于指定事务的传播行为,它决定了当前方法执行时,如何处理已经存在的事务
isolation 属性用于指定事务的隔离级别,它决定了当前事务与其他事务之间的隔离程度。
除了 propagation isolation 属性外, @Transactional 还支持其他属性,如 readOnly timeout
rollbackFor noRollbackFor 等,这些属性可以用于进一步细化事务的行为。
总之, @Transactional 注解是 Spring 应用中常用的事务管理注解。
@Configuration
@EnableTransactionManagement
public class AppConfig {
@Bean
public DataSource dataSource () {
// 配置数据源
}
@Bean
public JdbcTemplate jdbcTemplate () {
return new JdbcTemplate ( dataSource ());
}
@Bean
public PlatformTransactionManager transactionManager () {
return new DataSourceTransactionManager ( dataSource ());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 @Tranasctional 注解的使用注意事项
@Tranasctional 注解是 Spring 框架提供的声明式注解事务解决方案,在使用 @Transactional 注解时需
要注意以下问题 :
1. @Transactional 注解只能用在 public 方法上,如果用在 protected 或者 private 的方法上,不会报
错,但是该注解不会生效。
2. 默认情况下, @Transactional 注解只能回滚 非检查型异常,具体为 RuntimeException 及其子类和
Error 子类
非检查型异常指( Unchecked Exception )的是程序在编译时不会提示需要处理该异常,而
是在运行时才会出现异常。在 Java 中,非检查型异常指的是继承自 RuntimeException
的异常,例如 NullPointerException ArrayIndexOutOfBoundsException 等。这些异常通
常是由程序员的代码错误引起的,因此应该尽可能避免它们的发生,但是在代码中并不需要
显式地处理它们。
检查型异常( Checked Exception )是指在 Java 中,编译器会强制要求对可能会抛出这些异
常的代码进行异常处理,否则代码将无法通过编译。这些异常包括 IOException
SQLException 等等,它们通常表示一些外部因素导致的异常情况,比如文件读写错误、数
据库连接失败等等。
在编写代码时应该尽量避免抛出非检查型异常,因为这些异常的发生通常意味着程序存在严
重的逻辑问题。
默认情况下, @Transactional 注解只能回滚 非检查型异常,为啥呢 ?
可以从 Spring 源码的 DefaultTransactionAttribute 类里找到判断方法 rollbackOn
3. 如果需要对检查型异常( Checked Exception )进行回滚,可以使用 rollbackFor 属性来定义回滚
的异常类型,使用 propagation 属性定义事务的传播行为。
下面是一个例子:
上面的例子中 : 指定了回滚 Exception 类的异常为 Exception 类型或者其子类型检查型异常( Checked
Exception ),另外,配置类事务的传播行为支持当前事务,当前如果没有事务,那么会创建一个事
务。
4. @Transactional 注解不能回滚被 try{}catch() 捕获的异常。
5. @Transactional 注解只能对在被 Spring 容器扫描到的类下的方法生效。
其实 Spring 事务的创建也是有一定的规则,对于一个方法里已经存在的事务, Spring 也提供了解决方案
去进一步处理存在事务,通过设置 @Tranasctional propagation 属性定义 Spring 事务的传播规则。
Spring 事务的传播规则
Spring 事务的传播规则是指在多个事务方法相互调用的情况下,事务应该如何进行传播和管理。
Spring 事务的传播行为一共有 7 种,定义在 spring-tx 模块的 Propagation 枚举类里,对应的常量值定义
TransactionDefinition 接口里 , 值为 int 类型的 0-6
@Override
public boolean rollbackOn ( Throwable ex ) {
return ( ex instanceof RuntimeException || ex instanceof Error );
}
1
2
3
4
@Transactional ( rollbackFor = Exception . class , propagation =
Propagation . REQUIRED )
1 PROPAGATION_REQUIRED
支持当前事务,如果当前没有事务,则创建一个事务,这
是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务来执行
PROPAGATION_MANDATORY
支持当前事务,如果没有当前事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务执行操作,如果当前存在事务,则当前事务挂
起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有
事务,则进行与 PROPAGATION_REQUIRED 类似的操作。
稍后一点,结合源码介绍。