SQL Server事务和并发性的一些基础知识(未完待续)

浏览: 2101

事物和并发性

在学习事物和并发性之前首先来理解两个概念:

1、什么事事物?

事物是SQL Server中的基本工作单元。通常它由几个读取和更新数据库的SQL命令组成,但是这些操作都不被看为最终的,直到发出一个COMMIT命令为止。

2、什么是并发性?

并发性可以定义为多个进程在相同时间访问或者更改共享数据的能力。既然是能力,那么一个系统的并发性就会有强弱之分。既然如此,我们该怎样判断一个系统并发行的强弱呢?

一般情况而言,一个系统在互不干扰的情况下可以激活的并发用户的进程数越多,该系统的并发性就越强。

可能影响并发性的一些原因分析:

当正在更改数据的进程阻止其他进程读取该数据时,或者当读取数据的进程阻止其他进程更改该数据时,并发行会减弱。另外,当多个进程试图同时更改相同数据时,且无法在不牺牲数据的一致性的前提下都能成功时,并发性也会受到影响。对于并发性的理解我们和容易联想到铁道部的订票网站。由于处理并发性能力不够,导致订票高峰出现奔溃现象,对网络订票造成不良影响。由此可见,一个大型网站的数据库系统提高处理并发性的能力是在必要。

 

处理并发性的方法:

SQLServer 2008提供两种方法:乐观和悲观两个模型。我们可以通过一下命令来指定:

SETTRANSACTION ISOLATION LEVEL(事物的隔离级别)来指定。

两者的区别:

在两种模型中,两个进程试图在相同时间修改相同数据时,可能会出现冲突。那么这两个模型之间的区别在于冲突是在出现前被避免还是在出现后采取某种方式进行处理。

悲观并发模型:

对于悲观并发SQL Server默认的行为是获取锁来阻塞对另一个进程正在使用的数据的访问。悲观并发假设系统中有足够的数据修改操作,因而给定的任何一个读写操作都可能受到另外一个用户的数据修改操作的影响。悲观并发通过获得正在被读取数据上的锁,使其他进程无法修改该数据而避免冲突。换言之,在悲观模型下,读取者阻塞写入者,写入者也阻塞读取者。

 

乐观并发模型:

乐观并发假设系统中有足够少的数据修改操作,因而任何单个事物都不太可能另一个事物正在修改的数据。乐观并发的默认行为是使用行版本控制来允许数据读取者看到修改之前的数据状态。数据行教老的版本被保存,所以读取数据的进程可以看到进程开始读取时的数据,不会受到对该数据正在做出任何更改的进程的影响。换言之,读取者不阻塞写入者,写入者也不阻塞读取者,但是,写入者可以而且会阻塞写入者,这也是导致冲突的原因所在。这时SQL Server在冲突出现时产生一个错误信息,但是是由应用程序来负责影响该错误。

 

事务处理:

ACID属性

原子性:原子性保证每个事物被作为整体单元被处理或者不被处理,要么全部处理,要么全部不处理:

例如:

以下事物模拟银行转帐

Begintrabsaction tran1

Updatetb

setaccount=account+100  where accountid=’a’

updatettb

setaccount=account-100 where accounted=’b’

Committransaction tran1

以上简单的事物tran1中的两条语句要么都插入成功,要么都失败,不存在一条成功一条失败的现象。

换句话说,原子性保证了事物内部的所有语句被看作为一个原子,而原子是不可被分割的。

一致性:一致性确保事物不会允许系统达到不正确的逻辑状态。即使出现系统故障,也遵循所有的约束和规则。

例如上面的模仿银行转账的事物,事物的一致性确保了在a账户增加100远的同时b账户减少100元。避免了当a账户增加100后,系统出现故障而造成的b账户没有减少相应的资金。这确保了数据的一致性。

隔离性:隔离性将并发事物与其他未完成的事务的更新隔离开来。在上面的例子中,另一个事物无法看到这个正在执行的事物中所进行的工作。

持久性:在事物提交后,SQL Server的持久性属性确保事务的效果持久存在,即使出现系统故障亦是如此。

事物的依赖性

丢失更新:当两个进程读取相同数据,并且都操作数据,更改他的值,还试图将原始数据更新到新值,会出现数据丢失。例如:

A,B两个店员都接收到运来的部件。他们检查当前库存,并且看到存货当中还有25个部件。店员A收到的货是50个部件,所以他将50+25写入当前库存。店员B收到的是25个部件,所以他将20+25写入到数据库,覆盖了A添加的50个,这样就出现了数据更新丢失

脏读:脏读出现在进程读取未提交数据时。例如:A店员将原来的25个部件更新为75,在他提交之前,一个销售人员看到当前库存是75,并答应第二天给客户发60个部件。如果店员A发现这批零件中有缺陷,并且返回给供应商,并将库存更新为25,实际上就是销售人员进行了一次脏读,并基于未提交数据采取行动。默认情况下脏读是不允许的。

注意:更新数据的进程无法控制另一个进程是否可以在第一个进程提交之前读取他的数据。而是由读取数据的进程来决定它是否要读取不能保证已经提交的数据。

不可重复度:如果进程同一事物两次独立的读操作中读取相同的数据取得到不同的值,那么这样的读是不可重复的。

 

幻读:

 

事物的隔离级别:

未提交读:

已提交读:

可重复度:

快照:

可序列化:

每种隔离级别中允许的行为,如下表:

隔离级别         脏读         不可重复度     幻读         并发控制

未提交读         Y       Y       Y       悲观

已提交读(锁定)         N      Y       Y       悲观

已提交读(快照)         N      Y       Y       乐观

可重复度         N      N      Y       悲观

快照         N      N      N      乐观

可序列化         N      N      N      悲观

注:以上表格中的Y代表可以,N代表不可以

 

推荐 0
本文由 TravyLee 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册