2009-02-02 76 views
2

我有一个在终端上运行的应用程序。如何锁定表格的一行

终端在数据库表上注册。

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

这样做的最好方法是什么?

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

感谢:D

回答

4

在一般情况下,我尝试用短暂的锁,我可以在一个单一的做工作的整个单位上班(序列化)交易;这样可以避免需要额外的锁定机制,因为数据库锁会执行所有需要的操作。

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

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

为了应付未正确删除锁(因为死终端等)有3个常用的选项:

  • 时再次锁定的拥有者日志,让他们突破自己的锁
  • 允许管理员打破了用户的锁
  • 商店锁超时柱(日期时间),并有计划的任务将自动解锁逾期

所以要SUMM行出现 - 考虑是这样的:

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

+0

+1虽然我觉得需要澄清了不少,它完全有可能的业务需求,可以填补这个问题,而不需要一个复杂的数据库支持的会议方案 – 2009-02-02 13:21:20

0

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

也许你应该尝试添加一个名为“inUse”的列,并在终端使用它时将其设置为True(1)。如果终端已经设置,编程终端以遵守使用值,并确保在终端完成时将其设置为False(0)。

为什么该行无论如何都需要锁定,为每个终端设置一行会不会更好?

0

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

0

在许多SQL方言,你可以做这样的锁定:

begin transaction 

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

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

commit transaction