2009-02-02 21 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