代码改变世界

数据库事务

2014-07-27 01:14  Loull  阅读(236)  评论(0)    收藏  举报

先提一下基础知识,数据库事务的4个基本特性:

1.Atomic(原子性)

事务中包含的操作被看成一个逻辑单元,这个单元要么全部完成,要么全部没做。

2.Consistency(一致性)

隔离执行事务时(在没有其他事务并发的情况下)保持数据库的一致性。举例说明:A转账给B,那么此事务执行前和执行后A账户和B账户的总和是不变的。

3.Isolation(隔离性)

尽管多个事务可能并发执行,但是系统保证,对于任一事务Ti和Tj,在Ti看来,Tj或者在Ti开始之前已经完成执行,或者在Ti完成之后开始执行的。这样,每个事务都感觉不到其他事务在并发的执行。

4.Durability(持久性)

一个事务一旦执行成功,它对数据库的改变是永久的,即使系统可能出现故障。确保持久性是数据库系统中称为恢复管理部件的软件部件负责的。例如基于日志的恢复,远程备份系统等等。

事务的并发执行需要严格的管控,否则会出现各种问题:

1.Lost Update

在完全未隔离事务的情况下,两个事务更新同一条数据,其中一个事务异常终止,然后回滚,而在这个事务回滚之前另外一个事务提交成功,那么另外一个事务提交的数据会被回滚操作所覆盖。

2.Dirty Read

一个事务读到了另外一个事务未提交的新数据。

3.Phantom Read 

一个事务执行了两次查询操作(例如统计具有某特性的数据行数),但是两次查询操作中间,有其他事务插入了新数据或者删除了数据,造成两次结果不一致。

4.Unreapted Read

一个事务对同一条数据执行了两次读操作,但是读取的结果却不一样。出现原因:两次读操作之间有另外一个事务更新了这条数据。注意与Phantom Read区分,这里如果锁住要读的数据就不会出问题,但是对于Phantom Read仅仅锁住一行数据是没有用的!

5.Second lost Update

这是4的特殊情况,如果两个事务都读取同一行数据,都进行写操作并提交成功,那么第一个提交的事务所做的更新就会被第二个事务所覆盖。

 

要解决以上可能出现的并行问题,数据库一般都提供了事务隔离级别,不同的隔离级别解决问题的程度不一样。

1. Serializable 串行化
2. Repeatable Read 可重复读
3. Read Commited 可读已提交
4. Read Uncommited 可读未提交

这里推荐一篇文章http://www.cnblogs.com/zhujingyuan/archive/2009/11/12/1602193.html

此文中把隔离级别讲得很清楚了。对于SqlServer默认的事务隔离级别是Read Commited。已经可以满足大部分的应用场景了。