创作内容丰富的干货文章很费心力,感谢点过此文章的读者,点一个关注鼓励一下作者,激励他分享更多的精彩好文,谢谢大家!
@Transactional 是 Spring Framework 中常用的注解之一,它可以被用于管理事务。通过使用这个注解,我们可以方便地管理事务,保证数据的一致性和完整性。
在 Spring 应用中,当我们需要对数据库进行操作时,通常需要使用事务来保证数据的一致性和完整性。
@Transactional 注解可以被用于类或方法上,用于指定事务的管理方式。当它被用于类上时,它表示该类中所有的方法都将被包含在同一个事务中。当它被用于方法上时,它表示该方法将被包含在一个新的事务中。
@Transactional 注解有多个属性,其中最常用的是 propagation 和 isolation。
- propagation 属性用于指定事务的传播行为,它决定了当前方法执行时,如何处理已经存在的事务
- isolation 属性用于指定事务的隔离级别,它决定了当前事务与其他事务之间的隔离程度。
除了 propagation 和 isolation 属性外,@Transactional 还支持其他属性,如 readOnly、timeout、
rollbackFor、noRollbackFor 等,这些属性可以用于进一步细化事务的行为。
总之,@Transactional 注解是 Spring 应用中常用的事务管理注解。
@Tranasctional注解的使用注意事项
@Tranasctional注解是Spring 框架提供的声明式注解事务解决方案,在使用@Transactional注解时需要注意以下问题:
- @Transactional 注解只能用在public 方法上,如果用在protected或者private的方法上,不会报错,但是该注解不会生效。
- 默认情况下,@Transactional注解只能回滚非检查型异常,具体为RuntimeException及其子类和Error子类
非检查型异常(Unchecked Exception)指的是程序在编译时不会提示需要处理该异常,而
是在运行时才会出现异常。在 Java 中,非检查型异常指的是继承自 RuntimeException 类
的异常,例如 NullPointerException、ArrayIndexOutOfBoundsException 等。这些异常通
常是由程序员的代码错误引起的,因此应该尽可能避免它们的发生,但是在代码中并不需要
显式地处理它们。
检查型异常(Checked Exception)是指在 Java 中,编译器会强制要求对可能会抛出这些异
常的代码进行异常处理,否则代码将无法通过编译。这些异常包括 IOException、 SQLException 等等,它们通常表示一些外部因素导致的异常情况,比如文件读写错误、数
据库连接失败等等。
在编写代码时应该尽量避免抛出非检查型异常,因为这些异常的发生通常意味着程序存在严
重的逻辑问题。
默认情况下,@Transactional注解只能回滚非检查型异常,为啥呢?
可以从Spring源码的DefaultTransactionAttribute类里找到判断方法rollbackOn。
@Override
public boolean rollbackOn(Throwable ex) {
return (ex instanceof RuntimeException || ex instanceof Error);
}
3. 如果需要对检查型异常(Checked Exception)进行回滚,可以使用rollbackFor属性来定义回滚的异常类型,使用 propagation 属性定义事务的传播行为。
下面是一个例子:
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
上面的例子中: 指定了回滚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。
PROPAGATION_REQUIRED
|
支持当前事务,如果当前没有事务,则创建一个事务,这
是最常见的选择。
|
PROPAGATION_SUPPORTS
|
支持当前事务,如果当前没有事务,就以非事务来执行
|
PROPAGATION_MANDATORY
| 支持当前事务,如果没有当前事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务执行操作,如果当前存在事务,则当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED 类似的操作。 |
稍后一点,结合源码介绍。