mysql、innodb的事务acid、隔离级别、mvcc、读写锁、redo log、undo log

事务ACID

原子性(Atomicity):当前事务的操作要么同时成功,要么同时失败。原子性由undo log日志来实现

一致性(Consistency):使用事务的最终目的,由其它3个特性以及业务代码正确逻辑来实现

隔离性(Isolation):在事务并发执行时,他们内部的操作不能互相干扰,隔离性由MySQL的各种锁以及MVCC机制来实现

持久性(Durability):一旦提交了事务,它对数据库的改变就应该是永久性的。持久性由redo log日志来实现

持久性通过redo日志来保证

用户把name改为aa,先在内存把name改为aa,然后磁盘顺序写入redo log中name=aa。然后有空的时候,线程会把内存的name=aa写入磁盘的ibd文件中,即把磁盘中的name改为aa。

这样是为了性能,总不能用户一改name,就直接随机写入ibd中吧,老慢了。ibd是随机写,磁盘redo log是顺序写比较快。

如果内存崩了,那就磁盘redo log写入ibd,这样保证了持久性。

并发带来的问题(多个人同时操作同一数据带来的问题)

  • lost update  更新失效。我的更新被别人覆盖。

解决方法:加排他锁 、read uncommited 读未提交。

  • dirty read脏读。我读到别人还没提交的数据。

解决办法:read commited 读已经提交

  • non-repeatable read不可重复读。我每次读取的数据都要一样,不管其他人有没有刷新该数据,要可重复读,多用于报表(这个看需求,有的就需要可重复读,有的不需要,如就要看最新数据,那就是rc级别而不是这个rr级别) 。

解决办法:repeatable read 可重复读,生成快照。

  • phantom read幻读。我不要读到别人新增的数据,我之外的其他人的任何操作都不要影响到我。

解决办法:serializable  串行,读加读锁。

注意:

2、3、4都是侧重于读取方面的需求,1是侧重于更新(写)方面的需求

mysql的隔离是通过锁和mvcc来实现的

mysql默认隔离级别是repeatable read

mysql的读取(select)操作是可以加锁的:

share共享锁,s锁,读锁。其他可以读取,不能增删改。如何触发读锁,select ... lock in share mode

exclude排他锁,x锁,写锁。不能读取,不能增删改。如何触发写锁,select ... for update

mvcc(Multi-Version Concurrency Control 多版本并发控制)都有啥?

  • select是快照读(读历史的,事务开启时刻的),insert、update、delete是当前读(读最新的,这样才能在最新的数据上做更新,就不会在老数据上做更新了)
  • select的时候会生成快照:

rc和rr的快照范围不同。rc是在同一个事务中,每个select语句都重新生成快照(语句级快照)

rr是在事务开始时或者当前数据被自己数据更改时生成快照(事务级快照)

  • 快照需要undo log来实现:

如下图,事务A和事务B是在事务tx_id=2之后,tx_id=3之前开始的,三条select语句的发生时间分别是自己事务tx_id=A/B、tx_id=3、tx_id=4。

a7de760928aa4ba3af2ff9a174d5d400.pngcd5abe6cbfd74d70a0047427d70a486b.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值