4.3 事务
事务概念
事务状态
原子性与持久性的实现
并发执行
可串行性
可恢复性
隔离性的实现
SQL中事务的定义
检测可串行性事务概念
事务 是程序的逻辑运行单位
事务必须保持数据库的一致性
在事务执行过程中,数据库可能处于不一致状态
当事务提交时,数据库必须处于一致状态
要处理的两个问题,
– 各种故障,如硬件故障和系统崩溃
– 多个事务的并发执行
ACID 性质
原子性( Atomicity),事务的操作要么完全执行,
要么全不做
状态一致性( Consistency),在隔离状态下事务的执行保持数据库的一致性
隔离性( Isolation),尽管多个事务可以并发执行,每个事务必须不了解其他并发执行的事务,事务的中间结果对其他并发事务是不可见的
结果永久保持性 ( Durability),事务成功结束后,对数据库所做的更新将永久化,即使再发生系统故障也不受影响,
为保持数据一致性,数据库系统必须确保,
转账例
从账户 A 转移 $50到账户 B:
1,read(A)
2,A,= A – 50
3,write(A)
4,read(B)
5,B,= B + 50
6,write(B)
一致性要求 – 事务执行前后 A 与 B 之和保持不变,
原子性要求 – 若事务在第 3步之后及第 6步之前失败,系统应确保事务所做更新不被反映到数据库中,否则会出现不一致,
转账例 (续 )
持久性要求 — 一旦用户被告知事务已经完成 (即,
$50 转账已经发生 ),则即使发生故障,事务对数据库的更新也必须持久化,
隔离性要求 — 若在第 3步与第 6步之间允许另一事务存取部分更新的数据库,该事务将看到不一致的数据库 (A + B 小于正确值 ).
可通过串行 (即一个接一个 )执行事务来确保隔离性,但是并发执行多个事务具有很多好处,
事务状态
Active,初始状态 ; 事务执行时也处于此状态
Partially committed,最后一条语句执行之后,
Failed,发现不能继续正常执行之后,
Aborted,事务已回滚并且数据库已恢复到事务开始前的状态之后,此后有两种选择,
– 重启事务 – 仅当非内部逻辑错误时
– 杀死事务
Committed,事务成功结束之后,
并发执行
多个事务可同时运行,好处是,
– 增加处理器和磁盘的利用率,导致更好的事务 吞吐量,一个事务正在使用 CPU而另一个正在读写磁盘
– 减少事务的平均响应时间,短事务不应等在长事务之后,
并发控制方案 – 达到隔离性的机制,即控制并发事务的交互以防止它们破坏数据库的一致性调度
调度 –并发事务的指令按时间顺序执行的序列
– 事务集合的一个调度
必须包括所有事务的所有指令
必须保持各个事务内部的指令顺序
令 T1 从 A 转账 $50到 B,T2 从 A 转账余额的 10%
到 B,下列是一个串行调度 (教材中的 Schedule
1),先 T1 后 T2.
令 T1 与 T2 如前定义,不是串行调度,但与
Schedule 1等价,
Schedule 1 和 3都保持和 A + B.
下列并发调度 未能保持和 A + B.
可串行化
基本假定 – 每个事务都保持数据库的一致性,
故一组事务的串行执行也保持数据库的一致性,
一个 (并发 )调度是可串行化的当且仅当它与一个串行调度等价,不同形式的调度等价定义 (冲突等价和视图等价 )导致不同的可串行化概念,
1,冲突可串行化
2,视图可串行化
我们忽略除 read和 write之外的操作指令,并且假设在读和写之间事务对局部缓冲区内的数据可以执行任意的计算,简化的调度只包含 read与 write指令,
可恢复性
可恢复调度 — 若事务 Tj 读事务 Ti 先前写过的数据项,则
Ti 提交操作出现在 Tj 的提交操作之前,
下列调度 不是可恢复的,如果 T9 在读操作后立即提交
如果 T8 夭折,T9 则读了一个数据库的不一致状态 (并可能将结果显示给了用户 ),因此数据库必须确保调度是可恢复的,
需要考虑事务失败对并发执行的事务的影响,
级联回滚 – 单个事务失败导致一系列事务回滚,考虑下列调度,其中没有事务已提交 (因此该调度是可恢复的 )
若 T10 失败,T11 和 T12 也必须回滚,
导致大量工作的取消
无级联回滚调度 —不会发生级联回滚 ; 对每一对事务 Ti 与 Tj,若 Tj 读取 Ti 先前写过的数据项,
则 Ti 的提交操作必须出现在 Tj 的读操作之前,
每个无级联回滚调度也是可恢复的调度
有必要将调度限制为无级联回滚调度隔离性的实现
为保证数据库的一致性,调度必须是冲突或视图可串行化的,可恢复的,并且最好是无级联回滚的,
一次只允许一个事务执行的策略产生的都是串行调度,但并发度太差,
并发控制方案在它所允许的并发程度与带来的开销之间进行折衷,
某些方案只允许产生冲突可串行化的调度,而另一些则允许非冲突可串行化但视图可串行化的调度,
给定隔离级别允许和不允许出现的3种现象:
脏读:读取到未提交的数据;
不可重复读 (NonRepeatable read ):两次读涉及的数据行被修改或删除;
幻像读( phantom read):两次查询中允许其他事务插入数据。
SQL中的事务定义
数据操纵语言必须包含用来说明组成事务的操作集合的构造,
在 SQL标准中,事务是隐式开始的,
在 SQL中事务的结束是通过,
– Commit work 提交当前事务并开始一个新事务,
– Rollback work 导致当前事务夭折,
SQL-92中的一致性级别,
– Serializable — 缺省:最高
– Repeatable read:允许幻象读
– Read committed:允许不可重复读和幻象读
– Read uncommitted:允许脏读、不可重复读和幻象读并发控制的目标:确保调度的可串行化;
方法:测试方法不可用于并发控制;
原因:调度是各种因素综合起来的随机结果,
而测试是征对固定事务集合的某一固定调度。
ORACLE事务管理
ORACLE事务从第一个可执行的 SQL语句开始。一般无需显式地开始事务。
事务开始时,ORACLE给事务分配一个可用的回滚段。
以下情形下需结束一个事务:
发出一个 COMMIT,显式提交一个事务;
发出一个 ROLLBACK,显式回滚一个事务;
执行一个 DDL语句,在执行前后都隐式提交;
用户断开与 ORACLE的连接,当前事务被提交;
用户进程异常中断,当前事务被回滚。
在一个事务结束后,下一个执行的语句将自动启动下一个事务。
ORACLE在缺省情况下,读数据不加锁,通过回退段
(Rollback Segment)保证用户不读脏数据和可重复读,
回滚段中的数据是为事务服务的,每执行事务时,系统先在指定回退段上记录将要对数据进行的更改,以事务为单位,各个事务的回退信息链接在一起。
一个事务的回退信息按顺序在指定的回退段中写入。
创建多少个回退段及给每个回退段分配多少区间,要考虑可能出现的最大并发事务数,每个回退段所能同时服务的事务数。
当事务要回退时,利用回退信息将数据块中的数据恢复到先前的状态。
事务成功提交后,回退信息逐渐失效 (在提交之前申请的查询需要这些信息保证 读一致性,事务提交前对数据的变动不会为其他用户所知晓 )。回退段可以循环使用。
N
Y
进入回退段,写入回退信息从数据段读入缓冲区,SQL处理记载日志文件提交,写更改结果到磁盘 回退,写回退信息到磁盘事务第一条更新语句事务结束
ORACLE事务控制语句,
– COMMIT [WORK];
清除本事务的全部保留点,清除为执行事务建立的封锁机制,结束本事务,提交数据,
– SAVEPOINT 保留点名 ;
保留点是一事务范围内的中间标志,经常用于将长事务划分为短小的部分,保留点可标志在长事务的任何点,允许回退该点之后的工作,保留点主要作为一种调试手段使用,在一个事务中如果用相同的保留点名创建第二个保留点,则前一个保留点被删除掉,每个事务最大的活动保留点由初始化参数文件中的参数
SAVEPOINTS设定,
– ROLLBACK [WORK] [TO [SAVEPOINT] 保留点名 ];
清除本事务的全部保留点,清除为执行事务建立的封锁机制,结束本事务,回退数据,
数据定义语句 CREATE,DROP总引发提交,系统正常关闭时,未提交事务将隐式提交,一个进程或例程非正常终止,未提交事务将隐式回退。
– SET TRANSACTION [READ ONLY] [READ
WRITE] [USE ROLLBACK SEGMENT 回退段名 ];
设置事务是对事务的一种控制,建立当前事务为只读事务或读写事务,控制事务使用指定的回退段空间。只读事务不生成回退信息,所以不必分配回退段,缺省状态下事务为读写事务。
思考题:
1什么是事务?事务的特性?
2并发控制的目标是什么?
3 Oracle事务开始结束的标志。 Oracle事务控制的语句及功能。