无论隔离级别如何,单个语句UPDATES是原子的吗? (SQL Server 2005)

时间:2009-09-18 17:49:46

标签: sql-server-2005 sql-server-2008 transactions

在应用中,用户和案例具有多对多关系。用户经常拉出案例列表,用户可以一次更新一个案例(1-10秒操作,需要多个UPDATE)。在READCOMMITTED下,任何正在使用的Case都会阻止所有关联用户提取其案例列表。此外,最新的数据是对Cases表的读取和写入的热点。

我想我想用脏读来保持体验的活泼。 READPAST on Cases不适用于此目的。 NOLOCK可以工作,但我希望能够在列出时显示哪些记录是脏的。

我不知道有任何本地方式来显示哪些记录是脏的,所以我认为每次更新或插入到Cases时,都会设置一个INUSE标志。必须在更新事务结束时清除此标志,以便在READCOMMITTED下,此标志永远不会被设置。请注意,这不是要替换并发管理,而只是为了向用户显示哪些记录可能是脏的。

我的问题是这是否可靠 - 如果我们在一个语句中更新两个或多个字段(INUSE加上其他字段),并发NOLOCK查询是否可能读取一些新值而不读取其他值?如果是这样,是否可以保证首先设置INUSE?

如果我认为这一切都错了,请赐教。我理想的情况是,以可管理的方式,能够显示任何相关交易之前的价值,以便数据立即可用并始终保持一致(但部分过时)。但我不认为这是可用的 - 特别是在更复杂的实际数据库中。

谢谢!

2 个答案:

答案 0 :(得分:1)

重申问题只是为了确保:连接A上的用户A更新MyTable中的两列(col1,col2)。在此过程中,连接B上的用户B发出脏读,从该行中选择数据。您想知道用户B是否可以获得col1中的更新值以及col2中的旧/未更新值。正确的吗?

我不得不说:这不可能发生。据我所知,更新确实是一个原子事务,如果你正在向页面写入数据(在内存中),那么整个行更新必须在其他任何东西(另一个线程)可以获得之前完成该字节集访问它们。

但是我不确定,我无法想象如何设置测试以确认或否认这一点。我唯一依赖的答案必须来自实际上有代表编写代码的人,或者可能是具有类似访问权限的Microsoft技术人员。如果你在这里没有得到任何好的答案,在相应的MSDN论坛(link)上发布问题可能会得到一个很好的答案。

答案 1 :(得分:0)

您是否考虑过使用SNAPSHOT隔离级别?当用于查询时,它不需要任何锁定,并且它准确地给出了您要求的语义:

  

显示任何相关交易之前的价值,以便数据立即可用且始终一致(但部分过时)