SQL Server和Oracle中事务处理的特点
1 事务的特征(ACID属性)
n Atomic原子性就是事务应作为一个工作单元,事务处理完成,所有的工作要么都在数据库中保存下来,要么完全回滚,全部不保留。
n Consistent一致性 指事务中的操作保证数据库中的数据不会出现逻辑上不一致的情况,一致性一般会隐含的包括在其他属性之中。
n Isolated隔离性多个事务同时进行,它们之间应该互不干扰。应该防止一个事务处理其他事务也要修改的数据时,不合理的存取和不完整的读取数据。
n Durable永久性事务提交以后,所做的工作就被永久的保存下来。
2 事务的模式和开始结束时机
Ø SQL Server
n 自动事务
是指对于用户发出的每条SQL语句,SQL Server都会自动开始一个事务,并且在执行后自动进行提交操作来完成这个事务,也可以说在这种事务模式下,一个SQL语句就是一个事务。
可以这么理解,自动事务中每个DML或者DDL语句最后转化为下面的语句执行
BEGIN
Commit
DML/DDL
Commit (当DML/DDL错误时Rollback)
END
n 隐式事务
在当前会话中使用SET IMPLICIT_TRANSACTIONS ON/OFF可以启用/停止隐式事务。隐式事务从SET IMPLICIT_TRANSACTIONS ON后的第一个DML语句(数据操作语句,如insert、update、delete等)DDL语句(数据结构字典语句,如Alter、Create等)开始事务,在用户commit或者rollback后结束事务。
n 显式事务/用户定义事务
通过Begin transaction显示开始事务,commit/rollback提交或者回滚事务。
Ø Oracle
Oracle没有像SQL Server一样定义事务,没有transaction关键字。其事务都是由DML/DDL语句自动开始的,通过显示的Commit/Rollback提交/回滚。
Select语句不是严格意义的DML,在SQL Server他不会开始事务,因此只能通过Begin Transaction在Select之前开始事务。在Oracle中,由于没有显示的事务开始方式,此方法行不通,怎么办呢?Select的For Update子句可以使Oracle中的该Select语句隐式开启事务。
For Update子句还有一个重要的用途就是在SQL Server和Oracle中定义可修改的游标。
3 事务的隔离级别
3.1 并发的不利影响
n 更新丢失(lost update):事务A并不知道在他执行的过程中事务B已经对一个记录进行了修改,这时如果A也修改该记录,则事务B的修改可能丢失。
n 脏读(dirty read):事务中读到了其他事务尚未提交的数据;
n 不可重复读(nonrepeatable read):由于受到其他并行事务的影响,本事务先后读取同一数据得到了不同的结果(记录被修改过)。
n 幻读(phantom read):由于受到其他并行事务的影响,本事务先后读取同一数据得到了不同的结果(结果中出现了新的记录)。
3.2 并发控制
并发控制的技术很多,最重要的是锁机制。各种数据库系统实现的锁机制都大同小异,本文对锁机制不详细介绍。
3.3 ANSI定义的4种事务隔离级别
n READ UNCOMMITTED :一个会话可以读取其他事务未提交的更新结果,如果这个事务最后以回滚结束,这时的读取结果就可能是错误的,所以多数的数据库应用都不会使用这种隔离级别。
n READ COMMITTED :这是SQL Server的缺省隔离级别,设置为这种隔离级别的事务只能读取其他事务已经提交的更新结果,否则,发生等待,但是其他会话可以修改这个事务中被读取的记录,而不必等待事务结束,显然,在这种隔离级别下,一个事务中的两个相同的读取操作,其结果可能不同。
n REPEATABLE READ :在一个事务中,如果在两次相同条件的读取操作之间没有添加记录的操作,也没有其他更新操作导致在这个查询条件下记录数增多,则两次读取结果相同。换句话说,就是在一个事务中第一次读取的记录保证不会在这个事务期间发生改变。SQL Server是通过在整个事务期间给读取的记录加锁实现这种隔离级别的,这样,在这个事务结束前,其他会话不能修改事务中读取的记录,而只能等待事务结束,但是SQL Server不会阻碍其他会话向表中添加记录,也不阻碍其他会话修改其他记录。
n SERIALIZABLE:简单地说,SERIALIZABLE就是使事务看起来象是一个接着一个地顺序地执行。比如事务A和事务B并发执行,则根据TA和TB提交的先后,数据库中的数据必然先后出现两个时刻:A提交后和B提交后,这两个时刻数据都应该是完整的,正确的,且每个时刻的数据只和该事务开始时候的数据和事务的逻辑有关,与是否有其他事务正在执行无关。
3.4 SQL Server中的隔离级别
SQL Server中实现了ANSI定义的4种隔离级别,同时还增加了下面的两个级别:
n READ_COMMITTED_SNAPSHOT :如果事务A对数据进行了修改但尚未提交,事务B试图读取这些数据时将根据事务B的隔离级别发生:
u READ COMMITTED:等待事务A提交后才能读取;
u READ_COMMITTED_SNAPSHOT:忽略事务A对数据的更新,读取最后已提交的数据版本;
n ALLOW_SNAPSHOT_ISOLATION :如果事务A以REPEATABLE READ隔离级别进行,事务A读取了一些数据,则A将锁定这些数据以保证可重复读,其他事务只能等待A提交或者回滚。而如果A以ALLOW_SNAPSHOT_ISOLATION进行,则其他事务不必等待且可以更新这些数据,同时保证事务A的可重复读。
3.5 Oracle中的隔离级别
Oracle只实现了ANSI定义的4种隔离级别中的READ COMMITTED和SERIALIZABLE。