sql2005锁,隔离级别等一些相关问题(一)

因为压力测试的关系,所以数据库的那一块还需要更优化一下,锁的机制可能也需要调整下。因为本身虽然知道个大概,但也模模糊糊的,所以现在也重新系统的学习下。

首先来说明几个概念。

1.并发控制的类型  
当许多人试图同时修改数据库中的数据时,必须实现一个控制系统,使一个人所做的修改不会对他人所做的修改产生负面影响。这称为并发控制。
并发控制理论根据建立并发控制的方法而分为两类:

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

Microsoft SQL Server 2005 支持某个范围的并发控制。用户通过为游标上的连接或并发选项选择事务隔离级别来指定并发控制的类型。这些特性可以使用 Transact-SQL 语句或通过数据库应用程序编程接口(API,如 ADO、ADO.NET、OLE DB 和 ODBC)的属性和特性来定义。

2. 数据库引擎中的隔离级别

事务指定一个隔离级别,该隔离级别定义一个事务必须与其他事务所进行的资源或数据更改相隔离的程度。隔离级别从允许的并发副作用(例如,脏读或幻读)的角度进行描述。

事务隔离级别控制:

  • 读取数据时是否占用锁以及所请求的锁类型。

  • 占用读取锁的时间。

  • 引用其他事务修改的行的读取操作是否:

    • 在该行上的排他锁被释放之前阻塞其他事务。

    • 检索在启动语句或事务时存在的行的已提交版本。

    • 读取未提交的数据修改。

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

较低的隔离级别可以增强许多用户同时访问数据的能力,但也增加了用户可能遇到的并发副作用(例如脏读或丢失更新)的数量。相反,较高的隔离级别减少了用户可能遇到的并发副作用的类型,但需要更多的系统资源,并增加了一个事务阻塞其他事务的可能性。应平衡应用程序的数据完整性要求与每个隔离级别的开销,在此基础上选择相应的隔离级别。最高隔离级别(可序列化)保证事务在每次重复读取操作时都能准确检索到相同的数据,但需要通过执行某种级别的锁定来完成此操作,而锁定可能会影响多用户系统中的其他用户。最低隔离级别(未提交读)可以检索其他事务已经修改、但未提交的数据。在未提交读中,所有并发副作用都可能发生,但因为没有读取锁定或版本控制,所以开销最少。

SQL-99 标准定义了下列隔离级别,Microsoft SQL Server Database Engine 支持所有这些隔离级别:

  • 未提交读(隔离事务的最低级别,只能保证不读取物理上损坏的数据)

  • 已提交读(数据库引擎 的默认级别)

  • 可重复读

  • 可序列化(隔离事务的最高级别,事务之间完全隔离)

SQL Server 2005 还支持使用行版本控制的两个事务隔离级别。一个是已提交读隔离的新实现,另一个是新事务隔离级别(快照)。

  • 将 READ_COMMITED_SNAPSHOT 数据库选项设置为 ON 时,已提交读隔离使用行版本控制提供语句级别的读取一致性。读取操作只需要 SCH-S 表级别的锁,不需要页锁或行锁。将 READ_COMMITED_SNAPSHOT 数据库选项设置为 OFF(默认设置)时,已提交读隔离的行为与在 SQL Server 的早期版本中相同。两个实现都满足已提交读隔离的 ANSI 定义。

  • 快照隔离级别使用行版本控制来提供事务级别的读取一致性。读取操作不获取页锁或行锁,只获取 SCH-S 表锁。读取其他事务修改的行时,读取操作将检索启动事务时存在的行的版本。将 ALLOW_SNAPSHOT_ISOLATION 数据库选项设置为 ON 时,将启用快照隔离。默认情况下,用户数据库的此选项设置为 OFF。

下表显示了不同隔离级别允许的并发副作用。

隔离级别 脏读 不可重复读取 幻读

未提交读

已提交读

可重复读

快照

可序列化

有关每个事务隔离级别控制的特定类型的锁或行版本控制的详细信息,请参阅SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

以上取自MSDN里的描述。

但这里就算是锁还牵涉到一个行锁和表锁的问题。

原文地址:https://www.cnblogs.com/ziling8163/p/1360323.html