💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # 一、事务 ## 概念 事务指的是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollback 进行回滚。 ![](https://img.kancloud.cn/e2/fb/e2fb128e5bd99f7d834c35e75b9dd8f1_992x640.png) ## ACID ### 1. 原子性(Atomicity) 事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。 回滚可以用回滚日志(Undo Log)来实现,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可。 ### 2.一致性(Consistency) 数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对同一个数据的读取结果都是相同的。 ### 3. 隔离性(Isolation) 一个事务所做的修改在最终提交以前,对其它事务是不可见的。 ### 4. 持久性(Durability) 一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。 系统发生奔溃可以用重做日志(Redo Log)进行恢复,从而实现持久性。与回滚日志记录数据的逻辑修改不同,重做日志记录的是数据页的物理修改。 * * * 事务的 ACID 特性概念简单,但不是很好理解,主要是因为这几个特性不是一种平级关系: * 只有满足一致性,事务的执行结果才是正确的。 * 在无并发的情况下,事务串行执行,隔离性一定能够满足。此时只要能满足原子性,就一定能满足一致性。 * 在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。 * 事务满足持久化是为了能应对系统崩溃的情况。 ![](https://img.kancloud.cn/78/bf/78bfa0d8d89c5bf6eeca574159b7486f_767x353.png) ## AUTOCOMMIT MySQL 默认采用自动提交模式。也就是说,如果不显式使用`START TRANSACTION`语句来开始一个事务,那么每个查询操作都会被当做一个事务并自动提交。 # 二、并发一致性问题 在并发环境下,事务的隔离性很难保证,因此会出现很多并发一致性问题。 ## 丢失修改 T1和 T2两个事务都对一个数据进行修改,T1先修改,T2随后修改,T2的修改覆盖了 T1的修改。 ![](https://img.kancloud.cn/36/9b/369babf4b1544e68885f106d2c7ed8f2_807x425.png) ## 读脏数据 T1修改一个数据,T2随后读取这个数据。如果 T1撤销了这次修改,那么 T2读取的数据是脏数据。 ![](https://img.kancloud.cn/7c/a4/7ca4d52c09032ed29a0404f5115928a2_756x623.png) ## 不可重复读 T2读取一个数据,T1对该数据做了修改。如果 T2再次读取这个数据,此时读取的结果和第一次读取的结果不同。 ![](https://img.kancloud.cn/71/b5/71b5c3a0a5dddafa08916bdfd2ea2455_759x565.png) ## 幻影读 T1读取某个范围的数据,T2在这个范围内插入新的数据,T1再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。 ![](https://img.kancloud.cn/32/02/3202af2521b2098a4a67f3d8ff57b6e9_1030x702.png) 产生并发不一致性问题的主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。并发控制可以通过封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更轻松的方式处理并发一致性问题。 # 三、封锁 ## 封锁粒度 MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 应该尽量只锁定需要修改的那部分数据,而不是所有的资源。锁定的数据量越少,发生锁争用的可能就越小,系统的并发程度就越高。 但是加锁需要消耗资源,锁的各种操作(包括获取锁、释放锁、以及检查锁状态)都会增加系统开销。因此封锁粒度越小,系统开销就越大。 在选择封锁粒度时,需要在锁开销和并发程度之间做一个权衡。