Thursday, December 13, 2007

transaction isolation level


ANSI/ISOSQL 用三个必须在并行的事务之间避免的现象定义了四个级别的事务隔离。这些不希望发生的现象是:
丢失更新
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其他事务的存在。最后的更新将覆盖由其他事务所做的更新,这将导致数据丢失。
读污染(dirty reads)
一个事务读取了被另一个未提交的并行的事务写的数据。
不可重复的读(non-repeatable reads)
一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务修改过。
错误读取(phantom read)
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻读问题。即一个事务重新执行一个查询,返回一套符合查询条件的行,发现这些行中插入了被其他已提交的事务提交的行。
这四种隔离级别和对应的特性如下:

Isolation level

Dirty reads

Nonrepeatable reads

Phantoms

Read uncommitted

Yes

Yes

Yes

Read committed

No

Yes

Yes

Repeatable read

No

No

Yes

Serializable

No

No

No

并发控制理论根据建立并发控制的方法而分为两类:
  • 悲观并发控制
    一个锁定系统,可以阻止用户以影响其他用户的方式修改数据。如果用户执行的操作导致应用了某个锁,只有这个锁的所有者释放该锁,其他用户才能执行与该锁冲突的操作。这种方法之所以称为悲观并发控制,是因为它主要用于数据争用激烈的环境中,以及发生并发冲突时用锁保护数据的成本低于回滚事务的成本的环境中。
  • 乐观并发控制
    在乐观并发控制中,用户读取数据时不锁定数据。当一个用户更新数据时,系统将进行检查,查看该用户读取数据后其他用户是否又更改了该数据。如果其他用户更新了数据,将产生一个错误。一般情况下,收到错误信息的用户将回滚事务并重新开始。这种方法之所以称为乐观并发控制,是因为它主要用于数据争用较少的环境中,以及回滚事务的成本偶尔高于读取数据时锁定数据的成本的环境中。

Microsoft SQL Server 2005 支持某个范围的并发控制。用户通过为游标上的连接或并发选项选择事务隔离级别来指定并发控制的类型

事务隔离级别控制:

  • 读取数据时是否占用锁以及所请求的锁类型。
  • 占用读取锁的时间。
  • 引用其他事务修改的行的读取操作是否:
    • 在该行上的排他锁被释放之前阻塞其他事务。
    • 检索在启动语句或事务时存在的行的已提交版本。
    • 读取未提交的数据修改。

选择事务隔离级别不影响为保护数据修改而获取的锁。事务总是在其修改的任何数据上获取排他锁并在事务完成之前持有该锁,不管为该事务设置了什么样的隔离级别。对于读取操作,事务隔离级别主要定义保护级别,以防受到其他事务所做更改的影响。

读已提交Read Committed):当一个事务运行在这个隔离级别时,一个查询只能看到查询开始之前的数据而永远无法看到脏数据或者是在查询执行时其他并行的事务提交做的改变。

如果一个正在执行一个 UPDATE 语句(或者 DELETE 或者 SELECT FOR UPDATE)的查询返回的行正在被另一个并行的未提交的事务更新,那么第二个试图更新此行的事务将等待另一个事务的提交或者回卷。如果发生了回卷,等待中的事务可以继续修改此行。如果发生了提交(并且此行仍然存在;也就是说,没有被另一个事务删除),这个查询将对该行再执行一便以检查新行版本是否满足查询搜索条件。如果新行版本满足查询搜索条件,那么该行将被更新(或删除或被标记为更新)。

可串行化Serializable)提供最高级别的事务隔离。当一个事务处于可串行化级别,一个查询只能看到在事务开始之前提交的数据而永远看不到脏数据或事务执行中其他并行事务提交的修改。所以,这个级别模拟串行事务执行,就好象事务将被一个接着一个那样串行的,而不是并行的执行。

如果一个正在执行一个 UPDATE 语句(或者 DELETE 或者 SELECT FOR UPDATE)的查询返回的行正在被另一个并行的未提交的事务更新,那么第二个试图更新此行的事务将等待另一个事务的提交或者回卷。如果发生了回卷,等待中的事务可以继续修改此行。如果发生一个并行的事务的提交,一个可串行化的事务将回卷,并返回下面信息。

ERROR:  Can't serialize access due to concurrent update

因为一个可串行化的事务在可串行化事务开始之后不能更改被其他事务更改过的行。

0 comments: