了解Oracle的人都很了解Oracle数据库的行版本控制原理,它是通过undo段来存储数据行的多个版本信息。在sqlserver2005以前,sqlserver中在read committed隔离级别下的读写是相互阻塞的,这样也就降低了系统的并发性能。
2005中,sqlserver也实现了类似oracle的行版本控制,主要是通过增加了两个事务隔离级别:snapshot isolation(SI)和read committed snapshot isolation(RCSI),而且还有两个控制参数read_committed_snapshot和allow_snapshot_isolation,通过设置相应的参数与隔离级别,可以实现行版本控制,也就是说可以实现写不阻塞读。
一旦启用上面所说的隔离级别与参数设置,sqlserver使用tempdb来存储所有已经修改过的记录的副本,这个存储区称为版本存储区(version store)。用户在更新一行数据时,之前的版本在版本存储区,新的行包行一个指向更早版本的指针,一条记录的所有版本通过这个指针串联起来构成一个链表,因此sqlserver可能需要遍历这个链表才能得到一个正确的行版本。由此可见,如果开启了行版本控制,那么更新以及查询的性能会受到影响,但是提高了系统的并发性,两者本来就是相互制约的。
下面就简单介绍下sqlserver2005下两种支持行版本控制的隔离级别:snapshot和read committed snapshot。
首先,讲讲read committed snapshot。已提交读快照隔离通过设置read_committed_snapshot=on就可以,命令如下:alter database test set read_committed_snapshot=on;需要注意的是,如果执行该命令时还有用户在使用该数据库,这个alter命令就会被阻塞。可以通过alter database test set read_committed_snapshot=on with no_wait;来避免阻塞,这样就会报一个错误提示。这样,就实现了和oracle中同样的写不阻塞读,只有真正提交的数据才会被另外的事务访问,如果未提交,其他事务总是访问旧版本数据。
下面来说说snapshot隔离级别。如何修改?
首先,alter database test set allow_snapshot_isolation on;
然后得改变会话的事务隔离级别:set transaction isolation level snapshot;
这里要特别说明一下快照隔离级别与已提交读快照隔离的区别:
在快照隔离级别下,任何读取操作都将得到事务开始那一刻最近已提交的数据版本,而已提交读快照隔离会得到在语句开始那一刻最近已提交过的数据版本。而且快照隔离下事务的开始是在第一次访问数据库内任务数据时。
另外,数据库在SI模式下,不会对元数据进行版本控制,因此快照事务中某些DDL是不允许的。如下:
create/alter/drop index
dbcc dbreindex
alter table
alter partition function/schema
如下DDL是允许的,如create table/create type/create proc
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/165278/viewspace-462619/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/165278/viewspace-462619/