Mysql 事务隔离性

事务并发引起的问题

事务并发所引起的跟读取数据有关的问题,各用一句话来描述一下:

  1.脏读:事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。(读取未提交)

  2.不可重复读:事务 A 读取了事务 B 已提交的更改数据。(读取新提交update)

  3.幻读:事务 A 受到事务 B 已提交的新增数据影响。(看不到已提交更新,但是执行写操作时受影响)

 

事务隔离性

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。

 脏读不可重复读幻读
Read uncommitted
Read committed×
Repeatable read××
Serializable×××

隔离性测试:https://blog.csdn.net/johnstrive/article/details/46724315

https://www.cnblogs.com/huanongying/p/7021555.html

 

设置隔离级别

设置生效范围是当前事务 

mysql 5
select @@tx_isolation;
set tx_isolation='read-uncommitted';

mysql 8
select @@transaction_isolation;
set transaction_isolation='read-uncommitted';

Repeatable read(默认)

事务第一次执行select之后会记录快照,之后再执行select,只会读取快照内容。其他事务commit任何改变信息(insert,delete,update),对本事务不可见。会出现幻读现象,但是不影响当前事务执行Update,Insert的正确性。

一定要注意update、insert、delete 条件能够命中索引。否则将直接上表锁。

AB说明
select * fromn tb_pet;select * fromn tb_pet;A,B获取到的数据记录一致, 有数据(id,name,shl,ml) (3,“old”,1,500);
start transaction-事务A开始 
-start transaction事务开始
-insert into tb_pet(id,name,shl,ml) values(6,“bull”,1,1000);

B插入数据,上锁(事务B未提交,其他事物需要等待事务B提交才能修改)

 

 

update tb_pet set name="new",shl=2

where id=3

B修改数据,上锁
select * from tb_pet;select * from tb_pet;A没有获取到B插入的数据,不产生脏读,A产生tb_pet快照
-commit;事务B提交

select * from tb_pet;

结果:(3,“old”,1,500)

-A读取不到B新增和更新的数据,可重复读(此时事务A并未提交)

update tb_pet set name="first"

where id=3 and name="old" ;

-0行受影响。A看不到id=3的name已经被修改产生幻读。但是系统中已经没有符合条件的数据。

update tb_pet set shl=shl+1

where id=3 ;

-此时A以为结果数量会是2

select * from tb_pet where id=3;

结果:(3,“new”,3,500)

-产生幻读
insert into tb_pet(id,name,shl,ml) values(6,“bull”,1,1000);-A插入失败,报Duplicate key错误(i是主键),产生幻读,A查询不到id=6的记录,理论上可以插入该记录,但事实上B已经插入了这条记录,对于A来说幻读了id=6的记录
   
   

read-committed

两个mysql 客户端A,B, 都设置为 "read-committed"隔离级别,A设置事务不自动提交,B设置为事务不自动提交。

AB说明
select * fromn tb_pet;select * fromn tb_pet;A,B获取到的数据记录一致
start transaction-事务A开始 (事务A未提交)
-start transaction事务开始(事务B未提交)
-insert into tb_pet values(5,“mouse”,1,500);B插入数据(事务B未提交)
select * from tb_pet;select * from tb_pet;A没有获取到B插入的数据,不产生脏读
-commit;事务B提交
select * from tb_pet;-A读取到B新增的数据了,产生可重复读(此时事务A并未提交)

 

补充:

  1、事务隔离级别为读已提交时,写数据只会锁住相应的行

  2、事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。

  3、事务隔离级别为串行化时,读写数据都会锁住整张表

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值