Mysql数据库隔离级别锁关系脏读不可重复读幻读

数据库四大特性ACID

  • 原子性atomiticy:事务包含的所有操作,要么全成功,要么全部失败回滚
  • 一致性consistency:事务必须使数据库从一个一致性状态变成另一个一致性状态
  • 隔离性isolation:在多个用户并发访问数据库时,每个事务不能被其他事务所干扰,并发事务之间应该相互隔离
  •  持久性durability:事务一旦提交,数据即永久保存


数据库隔离级别


我们在进行数据库开发时经常会遇到程序事务的相关问题,对于脏读、幻读、不可重复读等问题的处理。

数据库隔离级别以及会出现的问题,如下表格:

隔离级别数据丢失脏读不可重复读幻读
读未提交Read uncommittedNoYesYesYes
读已提交 Read CommittedNoNoYesYes
可重复读 repeatable ReadNoNoNoYes
串行化 serializableNoNoNoNo

Mysql默认是可重复读

Oracle只支持两种级别,读已提交与串行化,默认为读已提交

 

  • 读未提交:一个线程在写事务的时候,添加一个X锁(排它锁),不允许其他线程事务对其进行操作,但是读不受限制,不加锁;会产生脏读
    1. 脏读:两个事务,一个事务进行了update操作,但未提交而回滚了,此时另一个事务读取到了未提交的数据,故此出现了脏读
    2. 示例:
事务A事务B

获取数据D的X锁

读取D的值1

D=D+1

D=2

写数据库

 

 

 

事务出错回滚操作

D=1

释放D的X锁

 

 

 

 

 

 

读取D的值

D=2

.........

 

 

 

这个时候B就发生了脏读,B得到的是2

其实数据中D依然等于1

  • 读已提交:事务写数据的时候添加X锁(排他锁),读数据的时候条件S锁(共享锁);并且有约定一个数据对于X锁S锁只能同时存在一个,但是可以同时存在多个S锁,并且规定读取完毕后,立即释放S锁。但是会产生不可重复读
    1. 不可重复读:同一个事务两次读取的数据不一致,即A事务读取了某个数据后,B事务将数据update了并提交,而A事务再次读取的时候,读到的是B事务修改后的结果,出现了两次读取不一样的情况
    2. 示例
事务A事务B

获取D的S锁

读取D的值1

D=1

释放D的S锁

.............

 

 

 

 

 

 

再次获取D的S锁

读取D的值2

释放D的S锁

此时D=2

 

由此就出现了不可重复读

两次读取的数据不一样

 

 

获取D的X锁

读取D的值2

对其进行修改

D=D+1

释放D的X锁

D=2

 

 

 

 

 

  • 可重复读:对S锁进行修改,由读取完数据后立即释放锁,改成知道事务要准备提交了才释放锁,对于X锁还是保持不变。但是会出现幻读
    1. 幻读:一个事务对某些数据进行了update,提交了,但是此时另一个事务又insert了一条类似的数据,当第一个事务在此查询的时候,发现还有一条记录没有update,即为幻读
    2. 示例
事务A事务B

获取D的X锁

读取到所有姓王的记录

修改所有姓王的人的成绩为60分

提交事务

释放D的X锁

此时D数据的年龄全部加了1

.............

 

 

获取D的S锁

读取D的数据

释放D的S锁

此时发现怎么还有一条姓王的人

的成绩不是60分

难道我出现幻觉了?

 

新增一条D数据也姓王成绩为50分

提交事务

 

  • 串行化:事务只能一件一件的进行,不能并行处理

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckjump

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值