SQL事务的系统梳理

数据库锁的升级过程和多线程锁的优化方式有点类似?
https://draveness.me/database-concurrency-control
读锁用来互斥写锁的,保证数据一致性。多线程有一个优化方向去了,cow等。
https://lishoubo.github.io/2017/10/23/%E4%B8%A4%E9%98%B6%E6%AE%B5%E5%8A%A0%E9%94%81/
2PL是这个意思,太细了吧。到不了这种优化级别吧

参考的文章大纲,一篇足够了。
https://blog.csdn.net/Jack__Frost/article/details/73347688
其他:
https://tech.meituan.com/2014/08/20/innodb-lock.html
https://blog.csdn.net/ai2713165/article/details/50488649
https://blog.csdn.net/whoamiyang/article/details/51901888
https://www.cnblogs.com/twoheads/p/10703023.html
http://blog.sina.cn/dpool/blog/s/blog_499740cb0100ugs7.html?vt=4
https://tech.meituan.com/2014/08/20/innodb-lock.html
算是理顺了mvcc,锁。

2:事务更像是一种结果。acid就是一个事务,孤独烟就说了,c是结果,aid是手段,
那什么是事务,就是acid,通过aid保证c的过程,就是一个事务,是进行并发控制的基本单元。

事务的隔离级别:
读未提交 脏读 读到别人临时修改的数据。
读已提交 不可重复读,两次读取的数据,被别的事务修改了,oracle就是这个级别。
不可重复读,他使用的next-key锁,但是,他没有锁住整个表,在事务里面,查询整个表,脱离了,next-key的控制范围,就会出现幻读。
大多的分享都是不可重复读级别的锁分享。
不对,加锁有聚聚索引,非聚聚索引,唯一索引的加锁过程分析。这些锁分析有什么实战的引导意义呢?
基本上分析都是到这里。
然后,7大锁的类型,都是先容,他们产生的背景呢?
读锁,写锁。
意向锁 产生的背景是为了高效互斥。


image.png

思考,意向锁都是彼此兼容的?因为粒度都是行锁,意向锁不会影响行锁。
当前是意向互斥锁,你要加意向互斥锁,可以的。因为大家的目的都是行锁,事务还是会继续下去,发现要加的记录有互斥锁,那就等待,如果不是一个记录,那就可以继续了,并发读在行上面。不同的事务不同的行,如果之间有业务逻辑,那就会死锁。
只要兼容就可以开启事务,也是死锁的根本原因,如果都是表锁,就没有问题了。


image.png

然后:
image.png

继续一点,看到目前的锁类型和加锁算法还是互斥这里。
思考:读写只有在同一个行记录上面,才会读写互斥,大多都不必要互斥,所以引入了MVCC,那写写冲突也是在行粒度上面,才是真的冲突,优化写写。

解决死锁的方法,还是超时,查看死锁的实际应用。

怎么回答MVCC
https://blog.csdn.net/ai2713165/article/details/50488649 图搜
https://blog.csdn.net/w2064004678/article/details/83012387 常规
https://blog.csdn.net/whoamiyang/article/details/51901888 常规
提供了互为相反的两种说法,很多的分享也都是copy的,有的分享说mvcc解决了幻读,大多都是认为没有的,应该是没有的。

image.png

是有争论的,三篇文章足够。
这个只能说,自己也是道听途说,没有实际的验证过,也没有遇到过这种场景和问题。
常见的说法是:mvcc类似cas,乐观锁。
image.png

主流的看mvcc。
image.png

在这一点上,都是共识的。
怎么实现了可重复读,是mvcc,具体一点就是,查询操作结果集满足两个条件
隐藏的2个ID,一个创建要小于等于当前的,是我事务开始就有的,那么新建的数据,你查询不到。同时,删除的要为null或者大于当前的,这也检索,是屏蔽别人的修改。
更新操作的本质是新建行,大家读取到的是old的,所以,对更新操作也是屏蔽的。

就这两篇文章,大家的讨论,把这个问题说清楚了。


image.png

image.png
image.png
image.png

mvcc解决了幻读吗?
/p/cef49aeff36b
这个问题真的大家都不是很清楚。

image.png

答案,是不能。
https://blog.csdn.net/fanghanwen_fei/article/details/77884891

image.png

这个文章不错,基本总结到位了
https://www.cnblogs.com/twoheads/p/10703023.html

image.png

标准答案。
image.png

那从这里,mvcc解决select这种可重复读没有问题,那种情况是mvcc无法解决的呢?
这个举例不好吧。
你得是别的事务影响,你不能自己影响自己吧
image.png

image.png

这里说的恰当了。
/p/cef49aeff36b 这个读幻读的概念理解错了吧

这么多的文章,没有一个人说的没有意义的,也看到这个问题了。
通过2个id,在有些情况下面是可以避免幻读的,隔告别的事务的干扰。
但是,在有些情况下,被影响了,就是你的事务里面也有修改操作。

但是,innodb的可重复读级别有幻读的问题,但是,是可以解决的?
mvcc+next-key锁,但是,是应用自己保证的。
https://www.cnblogs.com/twoheads/p/10703023.html
就这里,我觉得还好。
间隙锁为什么解决了对新增的幻读呢?除非你锁整个表呀,才不会幻读。
可重复读,就是不看到别的事务的提交。但是,你非用for update,那就看到了。
读已经提交,自然就不能重复读了。

image.png

mvcc都讲解明白了,但是,next-key没有说明白。

还是得看美团的文章
1:A 读不到B 也读不到C新加的数据。但是,A写一个C新加的数据呢?
就冲突了。
2:RR级别使用next-key锁,解决这个当前读的幻读。是当前读肯定是where 等值或者是范围。 如果就是select * from update ?业务也不应该这样吧。


image.png

行锁防止别的事务修改或删除,GAP锁防止别的事务新增,行锁和GAP锁结合形成的的Next-Key锁共同解决了RR级别在写数据时的幻读问题。
一句话总结。

再读这个,感觉都明了了,不像以前,可能沉不下心来。

这个理解了,直接取看多线程并发的锁优化。
OK,这个梳理下了,还是很有成就感的,不用着急,先把这5分钟搞定。

回到孤独烟的文章,回到主线,为了这5min中不冷场,怎么差异。

https://mp.weixin.qq.com/s/0c669K8vrIp3Qw6N77giYw
其实这里也比较浅,就4个属性的实现脉路。
都是理论常识,还是要到具体的实践里面。

回顾
https://blog.csdn.net/Jack__Frost/article/details/73347688
https://draveness.me/mysql-transaction
真是感知到了mysql源码级别的东西,主从同步的原理文章。

三篇继续
https://zhuanlan.zhihu.com/p/48327345
https://draveness.me/mysql-transaction
https://liuzhengyang.github.io/2017/04/18/innodb-mvcc/
NM,上来就这么宏大的框架。
是这样的,隔离是怎么实现的,隔离级别对应又是怎么实现的。这里引出的
和锁没有关系?锁是读写互斥。
更加细化的实现。

事务和锁有什么关系?事务的隔离性就是用锁来实现的,mvcc也是乐观锁。
也是看到这了,互斥 到读写,到cow。
一个事务就是一个快照,各个事务之间对数据的修改,就是mvcc控制了。
这里的脉路也很清晰。
https://liuzhengyang.github.io/2017/04/18/innodb-mvcc/
mvcc相比这种cow?更进一步?
理论,大家都没有实践,最忌讳说不清楚了。
可见性控制,是通过这个,read view视图来完成的呀。
NB,都深入到sql的源码级别了。
到视图这里,能说清楚一点就完美了。

再看ACID的实现,这都可以了。
https://draveness.me/mysql-transaction 终结站 相比孤独烟 终结了。

1:这里还不是双写,是先写日志,再写数据的。es的数据丢失粒度?保证性能,就双写了的。
2:他也是2阶段的,事务提交前,就已经记录日志了,所以,commit的时候,就是写库?如果45,那些log失败了,就
不能保证了呀。
3:读未提交,间隙锁的维度。是这个吗?
4:是这里,从事务的隔离级别到锁。
5:可以ZB的点呀,时间戳是postgre sql的,其他的是mvcc,都是类似的。
6:select for update 是为了在查询时,避免其他用户以该表进行插入,修改或删除等操作,造成表的不一致性.
https://blog.csdn.net/defonds/article/details/53131114 有坑的地方。
该业务代码先拿到该临时交易的锁,然后继续处理后续相当繁琐业务逻辑,中间还有大量的其它数据库操作,因为是声明式事务处理,所以在整个业务逻辑实行结束之后才会 commit,这段时间内如果还有其它 session 想拿这个行锁,就必须等到这一系列业务逻辑实行完毕。
正常情况下,这个逻辑是没问题的,但是在高并发的时候,这些业务逻辑受到 CPU 及网络等资源的限制可能会被拖慢,业务逻辑处理慢倒没什么,可怕的是数据库被拖慢,反过来又影响这些业务逻辑,形成一个滚雪球的效应,直至系统故障
在业务里面
https://blog.csdn.net/claram/article/details/54023216 基础回答。

对比一下两个人的回答。

还有数据库的索引,回答这个问题够了吧。看晕了都,99和0的区别,要逻辑清晰的
表达出来。

数据库的这个应该no problem了。
+++++++++++++++++++++++++++++++++++++++++sql end ++++++++++++++++++++++++++++++++++++++++++++++

netty,dubbo,rmq这些都会,但是,具体业务解决了什么问题,才是关键的。
否则这些理论常识,没有点呀,要不,都集中到天池的那个上取,dubbo-mesh,mq单机百万队列 这些都有了,看看怎么深入。
不懂的原理,就看表达了,zk和eureka 工作中遇到 注册等待,心跳时间过长的问题。
eureka可能注册更快,切换jsf等待时间更短。

关键的问题,必须清晰。RMQ的这整个流程,多线程多并发的基本代码code。
几大专题 遇到的问题。统一再梳理一下。

推荐阅读更多精彩内容