当前位置:   article > 正文

spring之@Transactional 简介_@transactional value属性

@transactional value属性
// 源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

	@AliasFor("transactionManager")
	String value() default "";

	@AliasFor("value")
	String transactionManager() default "";

	String[] label() default {};

	Propagation propagation() default Propagation.REQUIRED;

	Isolation isolation() default Isolation.DEFAULT;

	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

	String timeoutString() default "";

	boolean readOnly() default false;

	Class<? extends Throwable>[] rollbackFor() default {};

	String[] rollbackForClassName() default {};

	Class<? extends Throwable>[] noRollbackFor() default {};

	String[] noRollbackForClassName() default {};

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

1. @Transactional 属性

value

value 属性与 transactionManager属性互为别名,用于指定事务管理器。当存在多个数据源时,往往需要不同的数据源,使用不同的事物管理器,可以使用value属性,或者transactionManager属性指定具体的事物管理器。

transactionManager

@see value

propagation

事务的传播行为

假设当前有两个方法 A, B。方法A 调用了 方法B, A与B有都具有事务,当A 调用B 后,B的事务该怎样变化呢,这个就取决于设置的事务传播行为。事实上 B 的事务,大致有三种情况:第一 开启新的事务;第二 加入 A的事务;第三 以非事务的方式运行;
以下的例子均为 A 调用 B

  • PROPAGATION_REQUIRED:也是默认的事务传播行为。如果当前存在事务,则加入当前事务;如果当前不存在事务,则开启一个新的事务
    • 当前存在事务:A异常回滚时,B也会回滚;B异常回滚时,A也会回滚,同一个事务
    • 当前不存在事务:即 A 没开启事务,B会单独开启一个事务,当B回滚时,不会影响A, 当然 A中出现异常,也不会影响B;

  • PROPAGATION_SUPPORTS:如果当前存在事务,则加入当前事务(A,B同一个事务);如果当前不存在事务,则也不开启事务

  • PROPAGATION_MANDATORY:如果当前存在事务,则加入当前事务 (同一个事务);如果当前不存在事务,则抛出异常

  • PROPAGATION_REQUIRES_NEW:重新开启一个新事物;
    • 如果当前存在事务,当前事务对B不起作用,也就是当A发送异常时,只会回滚A中的数据,对B没有影响。但是如果B抛出了异常,且这个异常恰好满足A的回滚机制时,A会回滚。
    • 如果当前不存在事务:显然B不会影响A, 因为A不具有事务;A也不会影响B, 因为A中的异常,B也没法捕获

  • PROPAGATION_NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,当前事务只会对A生效,不会对B生效
  • PROPAGATION_NEVER:以非事务的方式运行,如果当前存在事务,抛出异常
  • PROPAGATION_NESTED 如果当前存在事务,则会作为当前事务的嵌套事务来继续运行。如果当前不存在事务,则会开启一个新事务。
    • 当前存在事务:当A 回滚时,B也会回滚;但是当B回滚时,不会影响A
    • 当前不存在事务:B会开启一个新事物,这个事务只作用与B, B回滚不会影响A

isolation

事务的隔离级别

事务的隔离级别即在多并发的情况下,多个事务之间的隔离程度

  • Isolation.DEFAULT 使用数据库默认的隔离级别。mysql 默认可重复读;oracle默认读已提交
  • Isolation.READ_UNCOMMITTED 读未提交
    • 允许读取还没提交的数据变更;这就可能造成脏读,幻读,不可重复读
    • 脏读:A 先修改了 table中的某条数据中的某个属性的值,但是还未提交数据,此时 B 同样查询了该属性值,就会导致 B查询出的是无用的数据。
    • 幻读:A读取了table中的一些数据,B在table中添加了一些数据,当A再次用相同的条件读取table中的数据,就会导致新查询出的数据多出几行,就像出现幻觉一样
    • 不可重复读:A 查询了table中的一些数据,B对这些数据进行了修改。当A 再次查询这些数据的时候,会导致两次查询出的数据不一样,导致不可重复读到原始的数据

  • Isolation.READ_COMMITTED 读以提交;可以避免脏读,但是幻读和不可重复读依然可能发生
  • Isolation.REPEATABLE_READ 可重复读;可以避免脏读和不可重复读,但是幻读可能发生
  • Isolation.SERIALIZABLE 序列化;可以避免脏读,幻读,不可重复读。但是严重影响程序性能

timeout

事务超时时间;即当事务运行时间超过 timeout时,会自动回滚事务,默认值为 -1 ,不设置超时时间

readOnly

只读;只允许事务进行查询操作,对于一次执行多条查询语句的,可以开启readOnly,可以保证整体读一致性。默认false

rollbackFor

事务回滚规则,接收指定异常进行回滚

  • 指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)
  • 指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName

事务回滚规则

  • 指定单一异常类名称:@Transactional(rollbackForClassName=“RuntimeException”)
  • 指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,“Exception”})

noRollbackFor

@see rollbackFor

noRollbackForName

@see rollbackForClassName

2. @Transactonal 作用范围

  1. 作用在类上:Transactional 对该类下所有public方法都生效
  2. 作用在 public方法上。但必须是 public修饰的方法
  3. 接口上;不推荐使用

3. @Transactional 失效的情况

  1. 被@Transactional 修饰的方法所在的类,没有被spring所管理。
  2. @Transactional 作用在 非 public方法上
  3. @Transactional 的事务传播行为设置错误
  4. @Transactional 的 rollbackFor属性设置错误
  5. 同一个类中调用的方法调用 @Transactional 修饰的方法。方法 A,B 属于同一个类,方法A 没有被 @Transactional 修饰,方法 B 被 @Transactional 修饰。 在 A 中调用 B。当外部的方法再调用A时,事务可能会失效。尽量将 @Transactional 修饰的方法抽离出来
  6. 异常被 catch 抓住,导致@Transactional 无法捕获异常
  7. 数据库引擎不支持事务
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/225500
推荐阅读
相关标签
  

闽ICP备14008679号