
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
事务是我们在学习软件编程开发技术的时候需要熟练掌握的一个编程知识点,而本文我们就通过案例分析来简单了解一下,事务处理常用方法都有哪些。
事务有四个的特性ACID:
原子性(Atomicity):事务中的所有操作都必须是原子的,即不可分割或撤销的。在一个事务执行期间,所有的操作都必须同时成功或同时失败,不存在中间状态。
一致性(Consistency):事务执行的结果必须保证数据库的一致性,即数据库中的数据必须在事务开始和结束时保持一致。
隔离性(Isolation):事务之间的操作相互隔离,即一个事务的操作不会受到其他事务的影响。
可用性(Availability):事务执行期间数据库必须保持可用,即可以在任何时候进行访问和修改。
这四个特性ACID中,C其实是目的,AID是手段。只靠内部(单数据源)可以用AID实现C,但是外部(多数据源)的情况下没法用AID保证C。
1本地事务
本地事务是一种基础的事务解决方案,适用单个服务使用单个数据源的场景。(注意,对于MyISAM来说,代码层面调用的rollback其实是空操作,引擎内置了事务处理,不需要代码调用rollback)本地事务的实现原理来自ARIES(基于语义的恢复与隔离算法)。
1.1本地事务如何实现原子性和持久性
本地事务中,写入磁盘的过程可能不是原子的,是会崩溃的。因此要考虑2个异常情况:
未提交事务(调用事务的应用层代码未返回成功),数据还没改完,写了一半崩溃了,导致数据不一致,非原子性
已提交事务(调用事务的应用层代码已经反悔了),但是实际磁盘内容还没写就崩了,导致数据完全没变化,非持久性。
解决方式:
引入commitlog,即将事务对数据的修改先写入commitlog,写入成功代表事务成功,写入完成后再写磁盘,如果中途崩溃了就重新写入,等同于熟知的redo-log!
这也是为什么redo-log中是针对某个物理块的修改,目的就是能正确重新,不用考虑我写到哪个位置了,直接全部重刷即可。
但是这样性能太慢,希望能在事务提交完成前提前写入磁盘,但是提前写的话可能会非原子。这时候就可以引入undolog,即触发回滚时,可以讲已操作的数据进行undo回滚操作。这也是为什么undo-log记录的是一条条不可重复执行的语句。
文中还提了2个特征:
NO-FORCE:事务提交后,不强求立刻全部写入磁盘,可以延迟(commit-log,有这的存在就不着急了);
STEAL:事务提交前,可以先写入一部分数据(undo-log)
1.2本地事务如何实现隔离性
隔离性主要就是依赖数据库锁和数据库隔离级别实现。书中用作者自己的话简述了一遍从可串行化到可重复读到读已提交到读未提交的演变过程和实现原理,也提了以下MVCC等内容。
看完后感觉和我这篇文章讲的内容基本对的上:将数据库9种锁、3种读、4种隔离级别一次性串联起来,用15张图呈现背后数据库事务背后的并发原理
里面有几句比较重要的话:
MYSQL/Innodb的“可重复读级别”只能在“只读”事务中解决幻读问题,但是读写事务还是会幻读;
读未提交仍然是包含了写锁的;
MVCC只是针对读+写的场景做了优化,如果是写+写是没法优化的,只能用锁;
范围锁不是指对范围内的每一条记录加锁,而是整个范围内甚至都不能做插入了,即包含了间隙的锁。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!请读者仅作参考。更多内容请加抖音达内三江区域学习了解。