mysql事务隔离级别

mysql事务隔离级别,第1张

mysql事务隔离级别如下:

1.读取未提交(READ-UNCOMMITTED):最低的隔离级别,允许读取尚未提交的数据变更,可能造成脏读、不可重复读、幻读。

2.读取已提交(READ-COMMITTED):允许读取并发事务已经提交的数据,可以避免脏读,但是可能造成不可重复、幻读。

3.可重复读(REPEATABLE-READ):对同一字段多次读取的结果都是一致的,除非本身事务修改,可以避免脏读和不可重复读,但是可能造成幻读。

4.可串行化(SERIALIZABLE):最高的隔离级别,完全服从ACID的隔离级别,所以的事务依次执行,可以避免脏读、不可重复读、幻读。

事务的特性:

1.原子性:事务最小的执行单位,不允许分割。事务的原子性确保动作要么全部执行,要么全部不执行。

2.一致性:执行事务的前后,数据保持一致。例如转账的业务中,无论事务是否成功,转账者和收款人的总额应该是不变的。

3.隔离性:并发访问数据库时,一个用户的事务不应该被其他事务所影响,各并发事务之间数据库是独立的。

4.持久性:一个事务被提交后,它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有影响。

SQL标准中支持4种事务隔离级别,READ_UNCOMMITTED(读未提交),READ_COMMITTED(读已提交),REPEATABLE_READ(可重复读),SERIALIZABLE(串行读),MySQL innodb引擎支持全部这4种事务隔离级别。

工具/原料:

联想Y7000P

Windows10

MySQL6.0

1、启动命令行窗口,连接MySQL数据库

图示,通过MySQL提供的客户端命令mysql连接MySQL数据库。

2、通过系统变量查询数据库当前事务隔离级别

图示,通过查询数据库提供的系统变量 tx_isolation 或 transaction_isolation 的值即可获取当前的事务隔离级别。MySQL数据库默认的事务隔离级别是REPEATABLE_READ (可重复读)。

3、设置本次会话的事务隔离级别

图示,通过命令set session transaction isolation level可以设置本次会话的事务隔离级别,该设置不会影响其他会话,并且设置会随着当前会话的结束而结束。

4、设置全局会话的事务隔离级别

图示,通过命令set global transaction isolation level可以设置全局会话的事务隔离级别,该设置不会影响当前已经连接的会话,设置完毕后,新打开的会话,将使用新设置的事务隔离级别。

5、设置一次 *** 作的事务隔离级别

图示,通过命令set transaction isolation level可设置下一次事务 *** 作的隔离级别,该设置会随着下一次事务的提交而失效。

众所周知,Mysql在InnoDB下有四种隔离级别:

未提交读(Read Uncommitted)

提交后读(Read Committed)

可重复读(Repeatable Read)

串行化(Serializable)

其中可重复读(RR)可以避免脏读( a事务读到b事务回滚前的数据)以及可不重复读( a事务在b事务修改提交的前后,两次分别读到的数据不一致)。但是对于幻读(a事务在b事务insert提交前后,两次分别读到的数据不一致),却存在争议。

下面我们来做一个试验:

对于下面这张简单的数据表

id        num

1         11

2         22

3         33

我们开启a、b两个事务

a事务                b事务

begin                begin

select * from tb    ----

----                    insert into tb (id,num)values(4,44)

----                    commit

select * from tb    ----

commit

试验结果:a事务的两次select查询到的结果相同,在后一次查询中没有返回新插入id=4的那条记录。

据此,很多人判断说RR隔离级别下“不存在”幻读。

但果真如此吗?----

出现上面的试验结果,是因为在RR隔离级别事务下,Mysql会对前一次select的结果快照。所以第二次select其实是快照读(这也正是RR隔离级别下能够避免不可重复读的策略)。

如果我们把试验条件稍作修改,同样开启a、b两个事务:

a事务                b事务

begin                begin

select * from tb    ----

----                    insert into tb (id,num)values(5,55)

----                    commit

update tb set num=num+1    ----        #此处a事务做一次修改 *** 作

select * from tb    ----

commit

试验结果:在a事务的第二次select中出现了b事务新插入的id=5的记录。

由于做了update *** 作,之前的快照失效了,所以说RR隔离级别下的快照策略并没能真正避免幻读。

ps. 假如给第二次的select查询上锁(无论是共享锁还是排它锁),也会得到同样的结果,都会令快照失效。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/6147336.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-16
下一篇 2023-03-16

发表评论

登录后才能评论

评论列表(0条)

保存