Spring注解事务行为
当事务方法被另一个事务方法调用时, 必须指定事务应该如何传播. 例如, 方法可能继续在现有事务中运行, 也可能开启一个新事务, 并在自己的事务中运行. 事务的传播行为可以在
@Transctional
的属性中指定, spring定义了 7 种传播行为, 具体如下图所示.
Spring传播行为
传播行为 | 含义 |
---|---|
PROPAGATION_REQUIRED | 如果当前没有事务, 就新建一个事务; 如果已经存在一个事务, 就加入这个事务中 |
PROPAGATION_SUPPORTS | 支持当前事务, 如果当前没有事务, 就以 非事务方式执行 |
PROPAGATION_MANDATORY | 使用当前的事务, 如果当前没有事务, 就 抛出异常 |
PROPAGATION_REQUIRES_NEW | 新建事务, 如果当前存在事务, 就 把当前事务挂起 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作, 如果当前存在事务, 就把当前事务挂起 |
PROPAGATION_NEVER | 以非事务方式执行, 如果当前存在事务, 就抛出异常 |
PROPAGATION_NESTED | 如果当前存在事务, 就在嵌套事务内执行; 如果当前没有事务, 就执行与PROPAGATION_REQUIRED类似的操作 |
##并发事务所导致的问题
隔离级别定义了一个事务可能接受其他并发事务影响的程度. 在典型的应用程序中, 多个事务并发运行经常会操作相同的数据来完成各自的任务. 并发虽然是必须的, 可是会导致许多问题, 并发事务所导致的问题可以分为以下三类:
- 脏读(Dirty Read): 脏读发生在一个事务读取了另一个事务改写但尚未提交的数据. 如果改写在稍后被回滚了, name第一个事务获取的数据就是无效的.
- 不可重复读(Nonrepeatable Read): 不可重复读发生在一个事务执行相同的查询两次或两次以上, 但是每次都得到不同的数据时. 通常是因为另一个并发事务在两次查询期间更新了数据
- 幻读(Phantom Read): 幻读与不可重复读类似, 发生在一个事务(T1)读取了几行数据, 接着另一个并发事务(T2)插入了一些数据时. 在随后的查询中, 第一个事务(T1)就会发现多了一些原本不存在的记录.
隔离级别
隔离级别 | 含义 |
---|---|
ISOLATION_DEFAULT | 使用数据库默认的事务隔离级别, 另外4个与JDBC的隔离级别相对应 |
ISOLATION_READ_UNCOMMITTED | 事务最低的隔离级别, 允许另一个事务可以看到这个事务未提交的数据. 这种隔离级别会产生脏读 , 不可重复度 和幻读 |
ISOLATION_READ_COMMITTED | 使用当前的事务, 如果当前没有事务, 就抛出异常 |
ISOLATION_REPEATABLE_READ | 新建事务, 如果当前存在事务, 就把当前事务挂起 |
ISOLATION_SERIALIZABLE | 以非事务方式执行操作, 如果当前存在事务, 就把当前事务挂起 |
@Transactional
可以通过propagation属性定义事务行为, 属性值分别为REQUIRED, SUPPORTS, MANDATORY, REQUIRES_NEW, NOT_SUPPORTED, NEVER 以及NESTED, 分别对应表1中的内容. 可以通过isolation
属性定义隔离级别, 属性值分别为 DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, 以及 SERILIZABLE.还可以通过 timeout 属性设置事务过期时间, 通过 readOnly 指定当前事务是否是
只读事务
, 通过 RollbackFor(noRollbackFor) 指定哪个或者哪些异常可以引起 (或不可以引起) 事务 回滚.
Over
如果觉得需要更多技术干货, 来我的CSDN 和 GitHub哦
我的博客: https://println.tk
Github: https://github.com/uweii