如何锁定表格的一行
Posted
技术标签:
【中文标题】如何锁定表格的一行【英文标题】:How to lock a line of a table 【发布时间】:2009-02-02 12:36:41 【问题描述】:我有一个在终端上运行的应用程序。
终端在数据库表上注册。
在应用程序在终端上运行的所有会话期间,我需要确保与终端对应的表的行被锁定并且没有人可以更新它。
最好的方法是什么?
我使用 C#.NET 作为编程语言,使用 SQL Server 作为 DBMS。
谢谢:D
【问题讨论】:
【参考方案1】:一般来说,我尝试使用短寿命锁,这样我可以在单个(可序列化)事务中完成整个工作单元;这避免了对额外锁定机制的需求,因为 db 锁将完成所需的一切。
使用长寿命锁时: 为此目的使用 rdbms-locks 是个坏主意——它根本无法扩展。时间戳或行版本列是进行乐观并发以防止意外覆盖的好方法。
要发布/强制执行正在编辑行的事实,我会将锁定用户的用户 ID/用户名存储在一列中(如果未锁定,则为空)。这清楚地表明谁拥有该行 - 即当您想要编辑该行时,首先更新它,设置您的用户 ID(并确保它尚未被锁定)。
为了处理未正确移除的锁(由于终端死机等),有 3 个常用选项:
当锁拥有者再次登录时,允许他们打破自己的锁 允许管理员破解用户的锁 存储一个锁定超时列(日期时间),并让计划任务自动解锁过期的行所以总结一下 - 考虑一下:
Foo
===
Id | ...data... | Timestamp | LockOwner | LockTimeout
---+------------+-----------+-----------+------------
等
【讨论】:
+1 虽然我确实认为这个问题需要澄清一下,但完全有可能在不需要复杂的数据库支持会话方案的情况下满足业务需求【参考方案2】:数据库不适用于这种锁定。您可以锁定项目,但仅限于操作期间(SELECT、INSERT、UPDATE、DELETE)。
也许您应该尝试添加一个名为“inUse”的位列,并在终端使用它时将其设置为 True(1)。对终端进行编程以尊重已设置的 inUse 值,并确保在终端完成时将其设置为 False (0)。
为什么无论如何都要锁定行,每个终端都有一行不是更好吗?
【讨论】:
【参考方案3】:执行此操作的最简单方法是假设您有协作进程并让终端应用程序(我假设它创建行)在创建行时生成并存储与该终端关联的唯一值。这样,在表中插入行的每个进程都有自己的唯一值,并且可以在更新表中的行时使用该值作为检查。如果您在事务中执行插入并读回插入的值,数据库可以为您生成唯一值(Guid 或 UniqueIdentifier 甚至只是一个整数标识字段)。
【讨论】:
【参考方案4】:在许多 sql 方言中,您可以执行这种锁定:
begin transaction
select * from FOOTABLE f for update where ID = '12345'
[... do any other stuff here ... ]
commit transaction
【讨论】:
以上是关于如何锁定表格的一行的主要内容,如果未能解决你的问题,请参考以下文章
滚动时如何锁定表格的第一行和第一列,可能使用 JavaScript 和 CSS?