sql server 2005使用基于行版本控制的隔离级别初探(续)
2009-08-19 21:13
429 查看
READ_COMMITTED_SNAPSHOT的演示: 下面演示一个使用AdventureWorks 数据库的READ_COMMITTED_SNAPSHOT的例子,方便大家理解READ_COMMITTED_SNAPSHOT 在此示例中,使用行版本控制的已提交读事务与其他事务并发运行。已提交读事务的行为与快照事务的行为有所不同。与快照事务相同的是,即使其他事务修改了数据,已提交读事务也将读取版本化的行。然而,与快照事务不同的是,已提交读将执行下列操作: 在其他事务提交数据更改后,读取修改的数据。 能够更新由其他事务修改的数据,而快照事务不能。 在会话 1 上: USE AdventureWorks; GO -- 在数据库上开启READ_COMMITTED_SNAPSHOT。 ALTER DATABASE AdventureWorks SET READ_COMMITTED_SNAPSHOT ON; GO -- 开始一个read-committed级别的事务 SET TRANSACTION ISOLATION LEVEL READ COMMITTED; GO BEGIN TRANSACTION; --选择EmployeeID号为4的员工的休假资料 SELECT EmployeeID, VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; 在会话 2 上: USE AdventureWorks; GO -- 开始一个事务 BEGIN TRANSACTION; --我们修改了EmployeeID为4的员工的休假资料 UPDATE HumanResources.Employee SET VacationHours = VacationHours - 8 WHERE EmployeeID = 4; -- 确认下现在EmployeeID为4的员工的休假资料 SELECT VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; 在会话 1 上: --因为会话2的事务没有提交, --EmployeeID为4的员工的休假资料因该没变 SELECT EmployeeID, VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; 在会话 2 上: --提交我们的更新 COMMIT TRANSACTION; GO 在会话 1 上: --OK,现在看看小4同志的资料 SELECT EmployeeID, VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; --现在我们也来尝试下修改小4同志的资料 UPDATE HumanResources.Employee SET SickLeaveHours = SickLeaveHours - 8 WHERE EmployeeID = 4; --ROLLBACK之后小4的数据到底是什么?你知道吗? ROLLBACK TRANSACTION; GO 回顾一下SNAPSHOT的构架: SNAPSHOT隔离就像真实的快照,它会无视涉及行的变化。在SNAPSHOT隔离下运行的事务将读取数据,然后由另一事务修改此数据。 SNAPSHOT事务不阻塞由其他事务执行的更新操作,它忽略数据的修改继续从版本化的行读取数据。但是,当快照事务尝试修改已由其他事务修改的数据 时,SNAPSHOT事务将生成错误并终止. 相比READ_COMMITTED_SNAPSHOT,SNAPSHOT真正做到了快照隔离,完全无视数据的更新。相对 READ_COMMITTED_SNAPSHOT,它更进一步减轻了对锁的依赖,在性能方面获得了更大的优势。不可避免的是,SNAPSHOT的事务性也 变得更差,但是,至少,它比NoLock要好。^_^ SNAPSHOT的限制: SNAPSHOT比READ_COMMITTED_SNAPSHOT更快,但是坏消息是它的限制也多。 1.快照隔离不支持分布式事务,包括分布式分区数据库中的查询。 2.SQL Server 不会保留多个版本的系统元数据。表中的数据定义语言 (DDL) 语句和其他数据库对象(索引、视图、数据类型、存储过程和公共语言运行时函数)会更改元数据。如果 DDL 语句修改一个对象,那么在快照隔离下对该对象的任何并发引用都将导致快照事务失败。READ_COMMITTED_SNAPSHOT 数据库选项为 ON 时,已提交读事务没有此限制。 例如,数据库管理员执行下面的 ALTER INDEX 语句。
3.BULK INSERT 操作可能会导致对目标表元数据的更改(例如,禁用约束检查时)。如果出现这种情况,访问大容量插入表的并发快照隔离事务将失败。 设置SNAPSHOT: 设置SNAPSHOT隔离模式也很简单,只要我们简单的一步操作就可以实现。 ALTER DATABASE DATABASE_NAME SET ALLOW_SNAPSHOT_ISOLATION ON; 但是要注意:如果 ALLOW_SNAPSHOT_ISOLATION 数据库选项设置为 ON,则数据库中数据已修改的所有活动事务完成之前,Microsoft SQL Server Database Engine 实例不会为已修改的数据生成行版本。如果存在活动的修改事务,SQL Server 将把该选项的状态设置为 PENDING_ON。所有修改事务完成后,该选项的状态更改为 ON。在该选项完全处于 ON 状态之前,用户无法在数据库中启动快照事务。数据库管理员将 ALLOW_SNAPSHOT_ISOLATION 选项设置为 OFF 后,数据库将跳过 PENDING_OFF 状态。 下面是ALLOW_SNAPSHOT_ISOLATION 选项的各个状态
下面是使用READ_COMMITTED_SNAPSHOT的一个例子: 在快照隔离下运行的事务可以访问数据库中为快照启用的表。若要访问没有为快照启用的表,则必须更改隔离级别。例如,下面的代码示例显示了在快照事务下运行 时联接两个表的 SELECT 语句。一个表属于未启用快照隔离的数据库。当 SELECT 语句在快照隔离下运行时,该语句无法成功执行。
在此示例中,在快照隔离下运行的事务将读取数据,然后由另一事务修改此数据。快照事务不阻塞由其他事务执行的更新操作,它忽略数据的修改继续从版本化的行读取数据。但是,当快照事务尝试修改已由其他事务修改的数据时,快照事务将生成错误并终止。 在会话 1 上: USE AdventureWorks; GO --在数据库上开启snapshot隔离级别. ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION ON; GO -- 开始一个snapshot事务 SET TRANSACTION ISOLATION LEVEL SNAPSHOT; GO BEGIN TRANSACTION; --选择EmployeeID号为4的员工的休假资料 SELECT EmployeeID, VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; 在会话 2 上: USE AdventureWorks; GO -- 开始一个事务 BEGIN TRANSACTION; --我们修改了EmployeeID为4的员工的休假资料 UPDATE HumanResources.Employee SET VacationHours = VacationHours - 8 WHERE EmployeeID = 4; -- 确认下现在EmployeeID为4的员工的休假资料 SELECT VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; 在会话 1 上: --因为会话二的事务没有提交, --EmployeeID为4的员工的休假资料因该没变 SELECT EmployeeID, VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; 在会话 2 上: --提交我们的更新,数据被更改了 COMMIT TRANSACTION; GO 在会话 1 上: --OK,现在看看小4同志的资料,被修改的数据被华丽的无视了 SELECT EmployeeID, VacationHours FROM HumanResources.Employee WHERE EmployeeID = 4; --现在我们也来尝试下修改小4同志的资料, --事务即将崩溃,请系紧安全带。^_^. UPDATE HumanResources.Employee SET SickLeaveHours = SickLeaveHours - 8 WHERE EmployeeID = 4; --ROLLBACK之后小4的数据到底是什么?你知道吗? ROLLBACK TRANSACTION GO |
相关文章推荐
- SQL Server 2005使用基于行版本控制的隔离级别初探(2) -- READ_COMMITTED_SNAPSHOT
- SQL Server 2005使用基于行版本控制的隔离级别初探(3) -- SNAPSHOT
- SQL Server 2005使用基于行版本控制的隔离级别初探(2
- SQL Server 2005使用基于行版本控制的隔离级别初探
- SQL Server 2005使用基于行版本控制的隔离级别初探(3)
- SQL Server 2005使用基于行版本控制的隔离级别初探(2) -- READ_COMMITTED_SNAPSHOT
- SQL Server 2005使用基于行版本控制的隔离级别初探(3) -- SNAPSHOT
- SQL Server 2005使用基于行版本控制的隔离级别初探
- SQL Server 2005使用基于行版本控制的隔离级别初探 .
- SQLServer2005使用基于行版本控制的隔离级别初探(1)
- 使用基于行版本控制的隔离级别
- 认清SQL_Server_2005的基于行版本控制的两种隔离级别
- 认清SQL_Server_2005的基于行版本控制的两种隔离级别
- sqlserver快照,启用基于行版本控制的隔离级别
- sql server行版本控制的隔离级别
- 【转修正】sql server行版本控制的隔离级别
- 使用VSS 6与SQL Server 2000集成存储过程版本控制的设置
- 使用SQL Server版本控制找回存储过程定义
- 在使用Sql server 2005 生成脚本时,出现目标服务器版本不支持该对象或不支持该对象的一个属性。 (Microsoft.SqlServer.Smo)的解决办法
- 如何通过在 SQL Server 的早期版本使用客户端工具连接到的 SQL Server 2005 或 SQL Server 2000 命名实例