什么是事务(transactions)
事务代表了 一组操作的集合,这些操作要么 全部执行,要么 全部不执行
ACID 特性
原子性
Atomicity
: 原子性,指事务的操作要么全部执行,要么全部不执行
假设我正在进行一个插入操作,要插入多条记录,那么这个插入操作就是一个事务,它会为插入的每条记录分配一个 事务号 XID,并将其记录在 事务提交日志 CLOG 中,然后 WAL 日志会记录修改,正常情况下,不会出现只插入一条记录的 中间状态,删除、更新操作也类似
一致性
-
Consistency
: 一致性,指事务的执行会导致数据从一个 一致的状态 转移到 另一个一致的状态,不违反预先定义的规则约束等等 -
MVCC
: 多版本并发控制,写事务不会原地修改元组内容,而是将被修改的元组标记为这条记录的一个 旧版本 (标记xmax),同时插入一条修改后的元组,从而产生这条记录的一个 新版本;对于在一个查询事务开始时还没有提交的写事务,那么这个查询事务始终认为该写事务没有提交
隔离性
-
Isolation
: 隔离性,指事务的执行过程中,所看到的数据库状态受 并发事务 的影响程度,受并发事务的影响 由重到轻 分为:读未提交,读已提交,可重复读,可串行化(也就是隔离性由低到高) -
异常现象
:-
脏读,指一个事务在执行过程中读到并发的、还没有提交的写事务的修改内容(看不见却看见了)
-
不可重复读,指在同一个事务内,先后两次读到的同一条记录的内容发生了变化(被并发的写事务修改)(值改变,数量不变)
-
幻读,指在同一个事务内,先后两次执行的、谓词条件相同的范围查询,返回的结果不同(并发写事务插入了新的记录)(值不变,数量改变)
-
持久性
Durability
: 持久性,指指一旦一个事务提交以后,那么即使数据库发生故障重启,该 事务的执行结果不会丢失,仍然对后续事务可见
预写日志 --- WriteAheadLog (WAL)
预写日志 是指在事务提交的时候,先将事务对于数据库的修改写入一个 顺序追加 的WAL文件中(对于真正修改的物理数据文件,等待合适的时机写入磁盘)
一般情况下,用户对数据的修改是较为随机的,在磁盘中分布比较分散,如果直接将这些分散的数据写入磁盘,性能比较差
所以可以 采用预写日志来避免持久化过程中的随机IO
- 日志记录 和 日志回放
在事务提交前将修改写入日志中,这样在当系统崩溃时能够将丢失的修改从日志中找回
总结
事务状态 --- Transaction States
Active(活动状态)
-
含义:事务处于执行阶段,即事务正在执行其操作(例如插入、更新、删除等)
-
描述:事务一开始就进入此状态,直到执行完所有语句
-
生命周期:事务开始时进入Active状态,执行SQL语句直到完成
Partially Committed(部分提交状态)
-
含义:事务执行到最后一条语句并完成时,进入部分提交状态
-
描述:事务的最后一条语句已经执行完成,但事务尚未提交。此时,如果没有错误,事务可以继续进行提交
-
生命周期:事务完成了所有操作,但还没有最终提交或终止
Failed(失败状态)
-
含义:事务由于某些原因无法继续执行,通常是由于系统错误或逻辑错误导致事务无法正常完成
-
描述:当事务遇到严重错误,不能继续执行时,它进入“失败”状态。例如,数据库出现故障或事务执行中发生了错误
-
生命周期:事务无法继续执行并需要处理
Aborted(中止状态)
-
含义:事务被中止并回滚,数据库被恢复到事务开始前的状态
-
描述:当事务因错误被中止时,所有已执行的操作会被撤销(回滚),并且数据库会恢复到事务开始之前的状态。事务不再有效
-
生命周期:事务出现问题或被主动终止后进入此状态,所有修改都被撤回
Aborted后的两种选择:
-
Restart the transaction(重新启动事务):如果事务没有遇到不可恢复的内部逻辑错误,可以重新启动事务并尝试再次执行。重新启动通常意味着事务会从头开始执行所有操作
-
Kill the transaction(终止事务):如果事务包含不可恢复的错误(如内部逻辑错误或严重的系统故障),则该事务会被完全终止,无法重新启动
-
Committed(提交状态)
-
含义:事务执行成功,所有操作都被永久保存到数据库中,事务完成
-
描述:事务在成功完成后进入提交状态。此时,所有的修改(如插入、更新、删除)会被永久保存到数据库中,且其他事务可以看到这些变更
-
生命周期:事务的所有操作都已成功执行并持久化,数据库已更新
调度 --- Schedule
调度 是指一组并发事务的操作按时间顺序排列的序列,即对并发事务进行排序
必须保证以下要求:
- 所有事务的操作必须被列出
- 保持事务内部的顺序
一个 成功 的事务会以 commit 作为最后操作,表示事务的所有更改都已永久提交
一个 失败 的事务会以 abort 作为最后操作,表示事务的所有更改都被撤销,数据库状态恢复到事务开始之前
可串行化 --- Serializability
基本假设
每个事务都保证数据库的一致性:也就是说,每个事务在执行过程中不会破坏数据库的合法状态,它的操作要么 完全成功(提交并持久化),要么 完全失败(回滚)
可串行化
如果一个调度的执行结果与某个串行调度的执行结果相同,那么该调度是 可串行化 的
-
串行调度 是指所有事务一个接一个地执行,没有并发,即事务之间没有交叉
-
可串行化调度 是指某个并发调度在结果上等价于一个串行调度,即在并发执行的过程中,虽然事务是交替执行的,但从最终的数据库状态来看,结果和串行执行的情况一样
调度等价性 --- Schedule Equivalence
冲突串行化 --- conflict serializability
-
冲突:
- 由不同事务执行
- 作用于同一数据项
- 其中至少有一个是写操作
-
冲突等价性:如果两个调度的操作顺序可以通过 交换不冲突的操作 来达到一致,那么这两个调度是冲突等价的
视图串行化 --- view serializability
视图串行化 的核心是 确保调度之间的读写一致性,而不关心具体操作的执行顺序。因此,它比冲突串行化宽松一些,但仍然能确保数据库在并发执行多个事务时的一致性
-
满足条件
-
初始值读取条件(Initial Read Condition)
如果某事务读取初始值,则必须在两个调度中都读取同样的初始值
-
读取写入值条件(Read-Write Condition)
如果某事务读取某数据项的值,并且该值由另一个事务写入,则两个调度中该读取- 操作读取的值必须一致
-
最终写入条件(Final Write Condition)
如果某事务执行了数据项的最终写操作,那么在两个调度中必须是同一个事务执行了该操作
-
优先级图 --- Precedence graph
优先级图是一个 有向图(Directed Graph),图中的 每个顶点(vertices)代表一个事务,图中的 有向边(arc)表示事务之间的冲突关系
边的方向 取决于 事务访问数据项的顺序。也就是说,如果在调度中,事务A访问了数据项,然后事务B对同一个数据项进行 冲突 操作,那么边的方向是 从A到B
有时会在边上加上 标签 用来表示哪个数据项引发冲突
当且仅当调度是 非环(acyclic) 的才是 冲突可串行化的,如下所示,调度(a)经过拓扑排序可以转变为(b)(c)
冲突可串行化可以通过优先图来测试,但是视图可串行化无法直接通过优先图来测试
标签:事务,串行化,调度,提交,------,操作,数据库系统,执行 From: https://www.cnblogs.com/dylaris/p/18624316