3

这是对是否可以在 SQL Server 中强制行级锁定的扩展. 这是用例

我有一个包含帐号、余额等的帐户表。该表被许多应用程序使用。很有可能,当我修改一个帐户时,其他人正在修改另一个帐户。所以预期的行为是我将锁定我的帐户(ROW),而其他用途将锁定他的(另一个 ROW)。

但是 SQL Server 2008 R2 将此锁定升级到页面/表,并且第二个用户得到超时异常。我已经尝试了引用问题中提到的所有解决方案,但没有任何效果。

如何强制 SQL Server 仅锁定行级锁,或者如何修改此模型以使其与页/表锁定一起使用?

编辑 该更新通过其 PK 以单个记录为目标,并且已编入索引,因此只有 ONE ROW 被更新/锁定,并且该过程不超过一分钟

编辑 现在看起来有些奇怪的事情正在发生。我正在为 DAL 使用一个 ORM 库,它打开了多个连接,我已经向他们的支持提出了这个问题。但是,出于测试目的,我在查询工具上打开了两个会话并做了以下操作

Session # 1
begin tran
UPDATE myTable SET COL_1 = COL_1 WHERE COL_1 = 101;

Session # 2
SELECT COL_1 FROM myTable WHERE COL_1 = 101;

Session # 2 中的查询超时!!!对其他值的查询COL_1工作正常。现在,如果同一记录在另一个会话中处于编辑模式,则看起来 SELECT 被阻止了一个会话。

尽管 Oracle 确实支持在其他会话修改行时选择行(使用默认参数/无关键字),但 SQL Server 不支持(使用默认参数/无关键字),因此问题似乎出在库上。

4

2 回答 2

9

默认情况下,SQL Server 始终使用行级锁定....那么您到底需要什么?

如果您锁定超过一定数量的行(大约 5000 行),那么 SQL Server 将执行锁定升级(锁定表而不是单独锁定超过 5000 行)以优化性能并优化资源使用 - 但这是一件好事!:-)

有一些方法可以完全关闭它 - 但不推荐使用这些方法!因为你搞乱了 SQL Server 存储引擎中的一个非常基本的机制。

看:

于 2012-05-18T07:30:46.407 回答
2

将您的系统想象成客户端-服务器应用程序,其中客户端和服务器通过非常慢的线路(例如蜗牛邮件)连接,并且用户正在很长时间(例如一周)修改他们的记录。然后想一想,何时需要锁定行/数据以及何时允许更改行/数据等等 - 显然将 SQL Server 内部锁定数天似乎不再是一个好主意。

如果您没有遇到两个用户需要更改同一条记录的情况,那么您在更改数据时根本不需要锁定。您只需要在很短的时间内锁定,当数据库中的记录发生更改时 - 换句话说,当用户提交更改时。(这是乐观锁定场景。)当然,如果两个用户更改相同的数据,那么最新的更改将覆盖之前的更改。

如果您绝对要求两个用户永远不要修改相同的数据(悲观锁定),那么可能最通用的方法是使用一些应用程序定义的锁表或数据表中的特定字段。当一个用户签出一些记录(开始编辑或类似时)时,您需要检查该记录是否已在使用(锁定),如果没有,则将此记录标记为锁定。当然,您需要一些功能来删除过时的锁。

或者针对这种情况使用 SQL Server 内部特定功能。看这里:MSDN 中的 sp_getapplock 函数;这样您就不必担心记录被永久锁定等。

于 2012-05-18T08:05:17.547 回答