如何锁定表格的一行

时间:2009-02-02 12:36:42

标签: .net sql

我有一个在终端上运行的应用程序。

终端已在数据库表中注册。

在终端上运行应用程序的所有会话期间,我需要确保与终端对应的表的行被锁定,没有人可以更新它。

这样做的最佳方式是什么?

我使用C#.NET作为编程语言,使用SQL Server作为DBMS。

谢谢:D

4 个答案:

答案 0 :(得分:4)

一般情况下,我尝试使用短期锁,我可以在一个(可序列化的)事务中完成整个工作单元;这避免了需要额外的锁定机制,因为数据库锁将完成所需的一切。

使用长寿命锁时: 为此目的使用rdbms-lock是一个坏主意 - 它根本不能扩展。时间戳或行版本列是进行乐观并发以防止意外覆盖的好方法。

要发布/强制执行正在编辑行的事实,我会将锁定用户的user-id / user-name存储在列中(如果未锁定,则为null)。这清楚地说明了谁拥有该行 - 即当您想要编辑该行时,首先更新它,设置您的用户ID(并确保它尚未被锁定)。

要处理未正确删除的锁(因为死终端等),有3种常见选项:

  • 当锁拥有者再次登录时,允许他们打破自己的锁
  • 允许管理员破解用户锁定
  • 存储锁定超时列(日期时间),并使计划任务自动解锁已逾期的行

总结一下 - 考虑一下:

Foo
===
Id | ...data... | Timestamp | LockOwner | LockTimeout
---+------------+-----------+-----------+------------

答案 1 :(得分:0)

数据库不适用于此类锁定。您可以锁定项目,但仅限于操作期间(SELECT,INSERT,UPDATE,DELETE)。

也许您应该尝试添加名为“inUse”的位列,并在终端使用时将其设置为True(1)。如果终端已经设置,则将终端设置为遵守inUse值,并确保终端设置为False(0)。

为什么行仍需要锁定,为每个终端设置一行不是更好吗?

答案 2 :(得分:0)

最简单的方法是假设您有合作进程并且在创建行时生成并存储与该终端关联的唯一值的终端应用程序(我假设创建该行)。这样,在表中插入行的每个进程都有自己的唯一值,并且可以在更新表中的行时将该值用作检查。如果您执行插入并在事务中读回插入的值,数据库可以为您生成唯一值(Guid或UniqueIdentifier,甚至只是整数标识字段)。

答案 3 :(得分:0)

在许多sql方言中你可以做这种锁定:

begin transaction

select * from FOOTABLE f for update where ID = '12345'

[... do any other stuff here ... ] 

commit transaction