文章目录
事务概念:
- 事务提交:
分为手动提交和自动提交,任何的DML数据操作语言:insert,update,drop,truncate等都会触发事务。
可以通过属性参数设置:
set @@autocommit = 0; #关闭自动提交。(不建议)
谈到事务,就必须知道事务的ACID性质:
- A 原子性
Atomicity
在每一个事务中,都可以看成是一个整体,不能将其再度分解,所有的操
作,要么一起成功,要么一起失败。 - C 一致性
Consistency
在事务执行前数据的所有状态跟执行后的数据状态应该是一样的。比如,转账前两个账户的金额总和应该跟转账后两个账户的总金额都是一样的。 - I 隔离性
Isolation
多个事务之间不能相互影响,必须保证其操作的单独性,否则会出现一些串改
的情况,执行的时候应该保持隔离的状态。 - D 持久性
Durability
如果我们的事务执行成功之后,它将把数据永久性存储到数据库中,哪怕设备关机之后,也是能够保存下来的。
事务的ACID性质是为了保证事务执行的安全性,是数据库在处理业务能收到欢迎的重要原因。
其中隔离性 isolation,主要针对多事务并发环境。两个或多个事务之间的隔离程度(操作之间不干扰 的程度);
首先了解一个概念:隔离等级:
出现的问题:
- 脏读:读到另一个事务执行修改而且还没有提交的数据。此时修改的数据还在innoDB的内存环节,属于脏页。但此时却被另一个事务读取到。
- 不可重复读:读到另一个事务修改而且已经提交的数据。会产生多次读数据不一致的情况。
- 虚幻读:读到另一个事务提交已经插入的数据。幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。不可重复读侧重表达 读-读,幻读则是说 读-写,用写来证实读的是鬼影。
虚幻读的解释
事务隔离等级:
TRANSACTION ISOLATION LEVEL = (RU,RC,RR)
1、READ UNCOMMITTED; 此时也不满足事务的隔离性和原子性。准确来说,此时的隔离等级已经不满足业务上对事务的定义了。
2、READ COMMITED;
3、REPEATABLE READ;
4、SERIALIZABLE ,此时串行化已经不是事务多发环境了,安全性最高,性能最低。
事务隔离性底层实现原理:
需要了解的是:RC 和 RR的实现机制。(RU不能严格上称为事务,SERIALIZABLE不需要考虑事务并发环境);
丢失更新问题
两个事务针对同一数据都发生修改操作时,会存在丢失更新的现象,这个问题称之为丢失更新问题。
举个栗子:
管理者要查询所有用户的存款总额,假设除了用户A和用户B之外,其他用户的存款总额都为0,A、B用户各有存款1000,所以所有用户的存款总额为2000。但是在查询过程中,用户A会向用户B进行转账操作。转账操作和查询总额操作的时序图如下图所示。
解决方法
LBCC (Lock Based Concurrency Control) 基于锁的并发控制
查询总额事务会对读取的行加锁,等到操作结束后再释放所有行上的锁。因为用户A的存款被锁,导致转账操作被阻塞,直到查询总额事务提交并将所有锁都释放。
这种方案比较简单粗暴,就是一个事务去读取一条数据的时候,就上锁,不允许其他事务来操作。假如当前事务只是加读锁,那么其他事务就不能有写锁,也就是不能修改数据;而假如当前事务需要加写锁,那么其他事务就不能持有任何锁。总而言之,能加锁成功,就确保了除了当前事务之外,其他事务不会对当前数据产生影响,所以自然而然的,当前事务读取到的数据就只能是最新的,而不会是快照数据。
MVCC (Muliversion concurrency control) 多版本并发控制
查询总额事务先读取了用户A的账户存款,然后转账事务会修改用户A和用户B账户存款,查询总额事务读取用户B存款时不会读取转账事务修改后的数据,而是读取本事务开始时的副本数据快照数据。