事务完整性

来源:互联网 发布:java电商网站 编辑:程序博客网 时间:2024/05/17 08:57

转载自:http://blog.csdn.net/szyjp/article/details/5144675


一、事务的基本概念:
    事务是一系列任务组成的逻辑单,这个逻辑单元中的所有任务必须作为一个整体要么全都完成要么全都失败。
 要把多条命令封装在一个事务中,只需使用很少的代码。只需使用两个标记来圈定整个事务的范围。
 一个标记位于事务开始处,而另一个则位于事务完成处,如果封装在事务内的代码检测到有错误发生,
 可以回滚或撤消整个事务。

begin transaction  ---标记事务开始
commit transaction  ---标记事务结束
rollback transaction  ---遇到错误就回滚

例句:
begin transaction      ---事务开始.....
 insert j_user(userid,username,password,usermain,notuse)
values(1037,'王运美',123,0,0)    ----开始插入第一条数据.....
if @@error <>0      ----如果遇到错误
begin
  rollback transaction     -----进行回滚...
raiserror('输入资料错误!',16,1)    ----提示错误原因
 return       ----撤消任务..
 end
 insert j_user(userid,username,password,usermain,notuse)
  values(1038,'杨静凯',123,0,0)    ----插入第二条数据...
if @@error <>0      ----如果遇到错误
begin
 rollback transaction     -----进行回滚....
raiserror('输入资料错误!',16,1)    ----提示错误原因
 return       ----撤消任务..
 end
commit transaction     ----事务结束

事务可以嵌套,但只要回滚了其中一个事务,所有未完成的事和都会一起回滚。

二、事务完整性
 事务完整性使用ACID特性来衡量事务的质量。违反事务完整性的问题有3类:
 脏读(dirty read)、不可重复读(nonrepeatable read)、幻影行(phantom rows)。
 要解决这3个问题,需要在事务之间使用不同的完整性或者隔离级别。

1. ACID属性
 ACID是4个相互独立的特性的首字母缩写:
 原子性(atomicity) 一致性(consistency)     隔离性(isoation) 持续性(durability)

 原子性:事务必须是原子的,在事务结束的时候,事务中的操作要么全都完成了,要么什么也没有做。如果事务中某些操作被写到磁盘上,而另外一些则没有,就违反了原子性。

 一致性:事务必须保证数据库的一致性,在事务执行前数据库应当处于一致状态,而当事务结束的时候,数据库又会回到一致性状态。数据库中的每一行和每个值必须与其所描述的现实保持一致,而且要满足所有约束的要求。如果将订单行写到了磁盘上,却没有写入相应的订单明细,则订单与订单明细之间的一致性就被破坏了。

 隔离性:和个事和都必须与其他事务产生的结果隔离开来。不管是否有其他的事务正在执行,事务都必须使用它开始运行的那一刻的数据集合执行下去。隔离性是两个事务之间的屏障。

 持续性:事务的持续性指不管系统是否发生了故障,事务处理的结果是永久的。一旦事务被提交后,它就一直处于已提交状态。数据库产品必须保证,即使存放数据的驱动器融化了,它也能够将数据恢复到硬盘驱动器融化之前,最后一个事务提交时的瞬间状态。

2。事务缺陷
事务之间缺乏足够的隔离性会表现在以下3个方面:脏读、不可重复读、幻影行。这些事务缺陷是影响事务完整性的隐患。

脏读:事务最明显的缺陷是在事务提交之前,它对数据所做的修改就为其他事务所见了。如果一个事务读取了另外一个事务尚未提交的更新,就叫脏读。 

 不可重复读:如果隔离性是完全的,那么一个事务不应该能看到本事务以外的数据更新。在一个事务内进行同样的读操作,每次都应该得到相同的结果。如果在两次读操作中得到了不同的结果,就意味着出现了不可重复读型事和缺陷。

幻影行:危害最小的事务完整性缺陷是幻影行。幻影行指的也是一个事务的更新结果影响到另一个事务的情况,但与不可重复读不同的是它不仅会影响另一个事务所选取的结果集中的数据值,而且还能够使 select 语句返回另外一些不同的记录行。

  总结: 脏读危害最大、不可重复读次之、幻影行的危害最小。

3。隔离性级别
 数据库产品是通过在事务之间建立隔离来处理3个事务缺陷的。隔离性级别,也就是事务之间隔离带的高度,可以根据具体
 需求加以调节以控制允许出现的事务缺陷。
  
 
隔离性级别 脏读 不可复读 幻影行    
read  Uncommitted
最不严格 可能 可能 可能    
read committed
SQL默认设置,中等严格 避免 可能 可能    
Repeatable Read  避免 避免 可能    
Serializable (最严格) 避免 避免 避免 

  SQL 使用锁来实现隔离性级别。鉴于锁会影响性能,用户必须在隔离级别和性能之间进行权衡。SQL 的默认级别是
 read committed ,这对于大多数 OLTP 项目都是适用的。

  read  Uncommitted  最不严格的隔离级别,它不能防止任何一种事务缺陷,因为它根本就没有在事务间提供隔离。
  read committed  防止了最严重的事物缺陷,而又不会使用系统陷入过度锁争用的泥潭。基于这个原因,SQL将它作为了
    默认的隔离级别。对于绝大多数的OLTP 项目来说,它都是一个理想的选择。
  Repeatable Read 可以防止脏读和不可重复读,它增加了事务的隔离级别,而因此带来的锁争用的压力又没有
    Serializable 隔离级别那样严重。
  Serializable  是最严格的隔离级别,它防止了全部的事务缺陷,这种模式适用于对于绝对的事务完整性的要求比性能更为重要的情况。银行、账务系统、销售数据库、股票、通常会使用Serializable隔离级别。这种设置虽然提供了完全的事务隔离,却会造成恶劣的锁争用,并使性能降低。

三、事务日志的架构
1。事务日志的顺序
 SQL 的设计之所以能够满足事务完整性的ACID特性的要求,在很大程度上是由于采取了预写日志。预写事务日志保障了每个事务的持续性。 
 dbcc opentran 命令可以获取最早的尚未提交的活动事务的信息

2。事务日志的恢复
 如果SQL停止了服务,在恢复服务时它将自动地对事务日志进行检查:
  事务日志中所记录的所有尚未提交的DM操作都会被回滚。
  对于那些在事务日志中所记录的已提交但还没有标记为已写入数据文件的条目,SQL在恢复时会将它们写入数据文件。

四、理解SQL的锁机制
 SQL用锁来实现事务之间的隔离,这样可以防止一个事务所操作的数据不受到另外一个事务影响。SQL 的锁不是锁定、释放页面那简单,而是相当复杂的,它具有多种多样的模式。因此只有先理解它,才能用好它。


原创粉丝点击