MySQL中关于事务的一些思考

115 阅读4分钟

什么是mysql事务?

首先,事务的作用就是为了保证ACID的特性的.

那什么是ACID?

ACID就是事务的基本特性,通过下列的特性保证了数据的完整性和一致性. 1.原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败回滚,事务不可部分完成。

2.一致性(Consistency):事务执行前后,数据库的状态必须保持一致。事务执行成功后,数据库应该从一个一致状态转移到另一个一致状态。

3.隔离性(Isolation):一个事务的执行不能被其他事务干扰,多个事务并发执行时,其执行结果应该与这些事务串行执行的结果相同。

4.持久性(Durability):一旦事务提交,其对数据库的更改应该永久保存,即使系统发生崩溃或故障,数据也能恢复。

为什么事物可以保证数据的完整性和一致性呢?

通过事务的第一点,执行过程要么成功,要么失败,不存在部分完成的情况.所以通过这一点可以保证事务的完整.

image.png转存失败,建议直接上传图片文件

通过事务的第二点,数据库中的外键约束、唯一约束等必须在事务开始前和结束后都保持满足。即使事务失败或出现错误,也会通过回滚机制(undo log)使数据库恢复到原始状态,保证数据不被破坏。

上述的意思就是事务的一致性操作,是有流程规范去约束的,事务的执行前后不能破坏数据库的规则和约束,例如不允许数据库对某个数据只操作一半,只有行和不行两种情况,别告诉我说,只有一半行,一半不行.

比如你开始转账时:

从账户A中减去100元, 同时向账户B中加上100元。 如果中途系统发生故障,或者事务出现错误,数据库必须确保:

要么两个操作都成功,账户A少100元,账户B多100元,这样数据是“合理”的。

要么两个操作都失败,账户A和账户B的余额保持不变,这也是“合理”的.

事务一致性保证问题解释.drawio.png转存失败,建议直接上传图片文件

通过上述两种就可以保证安全了吗?

通过上述如果单用户操作肯定是可以保证数据的安全的,但是现实的应用环境中,大多数都是并发执行的,那么可能会有什么问题呢?

还是以上述转账的例子,做一个解释说明 首先A还是给B转账100元, 但是过程中A去检测B账户增值的情况,发现已经新增100元,于是扣除自己账户的余额,可是没想到B在新增金额的时候失败了,导致数据没有更新成功,最后出现了双方账户额度都为0的情况.

脏读导致的事物数据混乱的情况.drawio.png转存失败,建议直接上传图片文件

上述就是典型的脏读现象,A读取了B未提交的数据,导致了数据的混乱,那么事务是如何进行解决这个现象的呢?

读已提交

这还不简单么, 上述出现脏读的情况就是读取了B没有提交的数据,我这次聪明了等B提交在读取就完事了.

读已提交解决脏读案例.drawio.png转存失败,建议直接上传图片文件

确实,通过读取已经提交的情况可以解决脏读的问题.那么我试试多次汇款看看有没有问题呢?

出现幻读的现象.drawio.png转存失败,建议直接上传图片文件

由于这个导致了A事务两次读取B余额的数据不一致,从而出现了幻象,咦,B脏读多出的钱是不是我弄错了吗??? 上述的情况就是事务中出现的幻读的现象,Mysql在InnnoDB中针对这种现象的解决方案是使用RR模式,也就是可重复读的事物+next-key-value锁的方式来解决幻读的产生.

那么RR模式是如何解决幻读的呢?什么是当前读?RR模式比RC模式的优点在哪里呢?为什么需要RR模式了还需要RC模式呢?

相信你也和我一样有很多疑惑, 让我们带着这些问题后续一起深入探究吧