mysql事务

1,事务的基本要素(ACID)

1.1 原子性:事务开始后的所有操作 要么全部成功 要么全部失败 但是不包括事务嵌套的情况 默认情况下 如果我们在一个事务A开启之后 再次开启另一个事务B 就会发生事务嵌套的情况 如果后台没有处理 则在开启事务B的时候 会默认将事务A已执行但是未提交的数据 直接commit 这会带来一个问题 就是一旦事务A未执行的部分 或者事务B执行失败 事务A无法彻底回滚 从而导致我们的程序出现脏数据 解决方案:mysql支持save point的功能 不清楚这个点的 可以自行百度 博主在此不做赘述

1.2 一致性:事务开始前 和结束后 数据库的完整性 是没有被破坏的。如 一个事务中 A向B转了1W 不可能出现A转了钱 B却没有收到

1.3 隔离性:同一时间 只允许一个事务请求 同一数据 不同事务之间 是彼此没有任何干扰的

1.4 持久性:事务完成之后 事务对数据库的修改 将是不可撤销的

2 事务的隔离级别

  RU(read-uncommitted): 读未提交 即一个事务可以读取另外一个未提交事务的数据 这个在日常开发中 几乎是不允许的 所以了解即可 没必要深究

  RC(read committed): 不可重复读 即一个事务在开始的时候 通过sql获取到A的值为1 在执行的过程中 二次查询数据库 再次获取的A的值为2 (原因是在执行的过程中 有其他事务对A的值 做了修改 并提交成功)  即幻读  解决方案:使用rr的事务隔离级别 或者 不要重复查询

  RR(repeatable-read): 可重复读(mysql 默认的隔离级别) 即每一个事务 都保存一份自己的快照 在事务为提交之前 所有的数据 都来自这个快照

  serializable:串行化 使用这个级别的事务 不会出现脏读、不可重复读以及幻读的现象 但是数据库的并发会被严格的限制 所以一般都不会采用这个级别的事务 了解即可

3 事务的并发问题

3.1 脏读:事务A读取了事务B中为提交的数据 然后事务B执行失败 回滚 导致了事务A中的数据被污染 这种现象主要发生在RU这个层级的事务隔离级别中

3.2 不可重复读:事务A在执行的过程中 多次获取了字段X的值 但是再最后一次获取之前 事务B对该字段做了修改 且成功提交了B事务 导致事务A在读取X值的时候 前后读取的值 不一致 主要对应的事务场景是RU - RC

3.3 幻读:事务A 在事务开启的时候 获取了满足某一条件 X 的所有数据 并执行了update / delete 的操作 在操作的过程中 事务B 执行了一次insert / delete 满足X条件的数据 并成功提交事务B 在事务A 执行完毕之后 再次查询满足X条件的数据时  发现仍有一条数据 未被修改 这就是幻读 主要对应的隔离级别为RU - RC - RR

Tip: 结合我们的实际应用中 只有RC和RR 是我们经常使用的事务隔离级别 所以我们的关注点 主要应该放在不可重复读 和 幻读身上 而二者又是非常容易混淆的 其最大的区别在于 不可重复读侧重于修改 幻读侧重于新增或删除 解决不可重复读的问题 只需要锁住满足条件的行 而解决幻读 则需要锁住表

原文地址:https://www.cnblogs.com/lovecatcher/p/15134473.html