MySQL事务的隔离级别

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MySQL事务的隔离级别
1. MySQL 事务隔离级别查看及修改参考:
1. 查看MySQL隔离级别
SELECT @@global.tx_isolation;
SELECT @@session.tx_isolation;
SELECT @@tx_isolation;
2. 修改MySQL 隔离级别
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
注意:默认的⾏为(不带session和global)是为下⼀个(未开始)事务设置隔离级别。

如果你使⽤GLOBAL关键字,语句在全局对从那点开始创建的所有新连接(除了不存在的连接)设置默认事务级别。

你需要SUPER权限来做这个。

使⽤SESSION 关键字为将来在当前连接上执⾏的事务设置默认事务级别。

任何客户端都能⾃由改变会话隔离级别(甚⾄在事务的中间),或者为下⼀个事务设置隔离级别。

2. MySQL 事务的隔离级别及每种隔离级别存在的问题参考:
1. 事务的四⼤特性
1. 原⼦性( Atomicity )
事务是数据库的逻辑⼯作单位,事务中包含的各操作要么都做,要么都不做
2. ⼀致性( Consistency )
务执⾏的结果必须是使数据库从⼀个⼀致性状态变到另⼀个⼀致性状态。

也就是说数据库中只包含成功事务提交的结果
3. 隔离性( Isolation )
并发执⾏的各个事务之间不会互相⼲扰
4. 持久性( Durability )
指⼀个事务⼀旦提交,它对数据库中的数据的改变就应该是永久性的
2. 事务的隔离级别
1. Read Uncommitted(读未提交)
所有事务都可以看到其他未提交事务的执⾏结果,会产⽣脏读(读取未提交的数据)
2. Read Committed(读提交)
⼀个事务只能看见已经提交事务所做的改变,会产⽣不可重复读问题
3. Repeatable Read(可重读)
这是MySQL的默认事务隔离级别,它确保同⼀事务的多个实例在并发读取数据时,会看到同样的数据⾏。

不过理论上,这会导致另⼀个棘⼿的问题:
幻读(Phantom Read)
4. Serializable(串⾏化)
这是最⾼的隔离级别,读加共享锁,写加排他锁,读写互斥,从⽽解决幻读问题。

在这个级别,可能导致⼤量的超时现象和锁竞争,如果业务并发的特
别少,同时⼜要求数据及时可靠的话,可以使⽤。

3. 隔离级别产⽣的问题
1. 脏读(Drity Read):某个事务已更新⼀份数据,另⼀个事务在此时读取了同⼀份数据,由于某些原因,前⼀个RollBack了操作,则后⼀个事务所读取的
数据不正确了
2. 不可重复读(Non-repeatable read):在⼀个事务的两次查询之中数据不⼀致,这可能是两次查询过程中间插⼊了⼀个事务更新的原有的数据。

3. 幻读(Phantom Read):在⼀个事务的两次查询中数据不⼀致,例如有⼀个事务查询了⼏列(Row)数据,⽽另⼀个事务却在此时插⼊了新的⼏列数据,先
前的事务在接下来的查询中,就会发现有⼏列数据是它先前所没有的。

读未提交可能会导致脏读、不可重复读、幻读
读提交可能会导致不可重复读、幻读
可重读可能会导致幻读
4. 事务的加锁机制
1. ⼀次封锁和两段锁协议
1. ⼀次封锁,在⽅法的开始阶段,已经预先知道会⽤到哪些数据,然后全部锁住,在⽅法运⾏之后,再全部解锁。

这种⽅式不会产⽣循环死锁的问
题,但数据库中在事务开始阶段,数据库并不知道会⽤到哪些数据,所以在数据库中不适⽤。

2. 两段锁协议
将事务分为加锁阶段和解锁阶段
1. 加锁阶段,在这个阶段只能进⾏加锁,读操作加共享锁,写操作加排它锁,有时候删除和插⼊操作会加区间锁
2. 解锁阶段,当事务释放了⼀个封锁以后,事务进⼊解锁阶段,在该阶段只能进⾏解锁操作不能再进⾏加锁操作。

事务加锁/解锁处理
begin;
insert into test ..... # 加insert对应的锁
update test set... # 加update对应的锁
delete from test .... # 加delete对应的锁
commit; # 事务提交时,同时释放 insert、update、delete对应的锁
这种⽅式虽然⽆法避免死锁(当事务A先需要资源1然后需要资源2,事务B 先需要资源2然后需要资源1),但是两段锁协议可以保证事务的并发调度是串⾏化
2. 悲观锁和乐观锁
1. 悲观锁:往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机
制,也⽆法保证外部系统不会修改数据)。

在悲观锁的情况下,为了保证事务的隔离性,就需要⼀致性锁定读。

读取数据时给加锁,其它事务⽆法修改这些数据。

修改删除数据时也要加锁,其它事务⽆法读取这些数据。

在MySQL InnoDB 中 RR 级别下,悲观锁加的是 next-Key锁
2. 乐观锁:基于数据版本( Version )记录机制实现。

为数据增加⼀个版本标识,读取出数据时,将此版本号⼀同读出,之后更新时,对此版本号
加⼀。

此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进⾏⽐对,如果提交的数据版本号⼤于数据库表当前版本号,则予以更新,否则认为是过期数据。

3.
在MVCC中为了减少锁处理(包括等待其它锁)的时间,提升并发能⼒,引⼊了快照读(读取历史数据)的概念,使得select不⽤加锁。

写(当前读):为了幻读问题,MySQL事务使⽤了Next-Key锁。

Next-Key锁是⾏锁和GAP(间隙锁)的合并,⾏锁防⽌别的事务修改或删除,GAP锁防⽌别的事务新增。

相关文档
最新文档