扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:builder.com.cn 2007年6月5日
在本页阅读全文(共3页)
我先前的SQL Server专栏中介绍了两种类型的数据表提示(table hints):NOLOCK和READPAST。
这篇文章将探讨在SQL Server中查询的时候,使用其它三种类型的数据表提示的优点和缺点,这三种类型分别是:READCOMMITTED、REPEATABLEREAD和SERIALIZABLE。
下面我们将通过一些实际的操作来了解数据表提示,我将创建一个表,并在这个表中插入一些数据。创建表和插入数据的代码都在Listing A中。
READCOMMITTED
使用SQL Server数据库表默认的行为是locking。当读取数据的时候,这个隔离类型使用共享锁,以便确保只有在数据被提交到数据库之后才能读取。使用这些锁是因为当对数据更新的时候需要排它性的锁,这种锁可以阻挡那些试图使用共享锁的所有读者。
对于绝大部分查询,这个分离层次能够很好的平衡数据库的一致性和同时性;然而,它也是有缺点的,它的缺点就是不可重读(Non-Repeatable read)和幻读(phantom read)。
下面就是使用READCOMMITTED的一个例子。在这个例子中,你需要有查询编辑窗口或者数据库连接到Session 1和Session 2.
Session1:
BEGIN TRANSACTION
UPDATE SalesHistory
SET SalePrice = SalePrice + 1
WHERE SaleID = 201
Session2:
BEGIN TRANSACTION
SELECT * FROM SalesHistory WITH(READCOMMITTED)
这个查询大约返回表的前200条记录。(它可能不会准确的返回200条记录,那是因为第一个会话可能使用page锁,这种锁会把数据的某页锁住,而不是锁住单条记录。)一旦第一个200或者大约这么多条记录被返回了,查询将继续运行,但是不会返回另外的行了。
这个查询会等待,直到从第一个更新语句开始就被锁住的事务释放掉它的锁。我能看到第一个200或者大约这么多条记录的数据。注意,我创建的那个事务一直是打开的。
Session1:
UPDATE SalesHistory
SET SalePrice = SalePrice + 2
WHERE SaleID = 1
COMMIT TRANSACTION
这个更新语句一直等待最初的事务范围。我用SaleID=1来更新记录,这样在Session 2中的事务将返回一行记录。一旦我提交了这个事务,Session 2的查询操作就完成了。
Session2:
SELECT * FROM SalesHistory WITH(READCOMMITTED)
COMMIT TRANSACTION
我又一次进行同样的查询。虽然它一直在同一个事务中,但是这时候,当SaleID = 1时SalePrice的返回值就不同了。这就是所谓的不可重读(Non-Repeatable read)。
我在同一事务中操作的数据如果在事务外部被改变了的话,可能会对后面的事务产生不利影响。这就是这种事务隔离水平的两个可能的副作用中的一个——另外一个类型是“幻影”读(phantom read)。(我将在REPEATABLEREAD部分详细的介绍幻读。)
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者