一、概念
数据库的事务是用来维护数据的完整性和一致性,保证处理数据时,要么全部执行,要么全部不执行。
事务的四个属性(特性):
原子性(Atomicity):
即一个事务作为一个最小执行单元,不可分割。包含在内的所有操作要么全部被执行,要么都不执行。
一致性(Consistency):
事务确保数据库的状态从一个一致状态转变为另一个一致状态。
隔离性(Isolation):
多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):
一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。

在这个过程中可能会出现以下几种情况:
1. 用户A转账的第一步,扣款成功,此时系统发生异常,但用户B账户还没有增加相应的金额。(原子性/一致性)
2. 用户A转账的第一步扣款成功,给用户B增加金额成功,但没提交事务,用户B去查询自己账户月,发现已到账。此时系统崩溃,事务回滚,用户B再去查询,发现账户金额还原了。(持久性)
3. 同时又有另一个用户C转账给B账户,由于同时对B账户进行操作,有可能会导致B账户金额出现异常。(隔离性)
MySQL事务隔离级别
| 事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
| 读未提交(read-uncommitted) | 是 | 是 | 是 |
| 不可重复读(read-committed) | 否 | 是 | 是 |
| 可重复读(repeatable-read) | 否 | 否 | 是 |
| 串行化(serializable) | 否 | 否 | 否 |
mysql默认的事务隔离级别为repeatable-read 可重复读,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
脏读: 事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。
不可重复读: 事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。一般是由update时引发的问题
幻读: 事务A在修改一些数据时,事务B插入了一条数据,事务A修改完以后进行查询,发现还有一条数据没有被修改,就好像发生幻觉一样。一般是insert或delete时引发的问题
注:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
Spring事务的传播机制
事务的传播性一般用在事务嵌套的场景,比如一个事务方法里面调用了另外一个事务方法,那么两个方法是各自作为独立的方法提交还是内层的事务合并到外层的事务一起提交,这就是需要事务传播机制的配置来确定怎么样执行。
常用的事务传播(PROPAGATION)机制如下:
| 事务隔离级别 | 说明 |
| REQUIRED | Spring默认的传播机制,能满足绝大部分业务需求,如果外层有事务,则当前事务加入到外层事务,一块提交,一块回滚。如果外层没有事务,新建一个事务执行 |
| REQUES_NEW | 每次都会新开启一个事务,同时把外层事务挂起,当前事务执行完毕,恢复上层事务的执行。如果外层没有事务,执行当前新开启的事务即可 |
| SUPPORT | 如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务 |
| NOT_SUPPORT | 不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码 |
| NEVER | 该传播机制不支持外层事务,即如果外层有事务就抛出异常 |
| MANDATORY | 与NEVER相反,如果外层没有事务,则抛出异常 |
| NESTED | 该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。 |
事务的传播规则回答了这样一个问题:一个新的事务应该被启动还是被挂起,或者是一个方法是否应该在事务性上下文中运行。具体在Spring中的使用。
具体在Spring中使用,如:@Transactional(propagation = Propagation.REQUIRED)
2697

被折叠的 条评论
为什么被折叠?



