美文网首页
SQL事务的系统梳理

SQL事务的系统梳理

作者: 辰晞 | 来源:发表于2019-05-15 07:25 被阅读0次

    数据库锁的升级过程和多线程锁的优化方式有点类似?
    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解决了幻读吗?
    https://www.jianshu.com/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
    这里说的恰当了。
    https://www.jianshu.com/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。
    几大专题 遇到的问题。统一再梳理一下。

    相关文章

      网友评论

          本文标题:SQL事务的系统梳理

          本文链接:https://www.haomeiwen.com/subject/qghuaqtx.html