2011-06-01 73 views
1

我的C#程序中執行以下操作(僞代碼):數據庫行鎖定

START TRANSACTION READ COMMITTED 
Select isOriginal, * from myTable where tnr = x; 
//Record found? 
Yes: 
    //isOriginal? 
    Yes: 
    update myTable set is_active = 0 where tnr = x; 
    No: 
    delete from myTable where tnr = x; 
    //Do some simple logic on the values 
    Insert into myTable (newvalues) 
No: 
    return record_not_found; 
END TRANSACTION 

然而,當我開始我的程序的兩個實例,並都同時插入兩個記錄作爲編輯同一條記錄他們都在選擇查詢中找到記錄。

應該發生的事情是第一個事務找到記錄並插入一個新行,而第二個事務返回一條未找到的記錄。

我該如何解決這個問題?把我的交易序列化?檢查更新/刪除的返回值?最好的方法是什麼?

編輯

應該基於Sybase,甲骨文& SQL Server的工作。

+0

您使用什麼數據庫只是做? – 2011-06-01 14:33:45

+0

你肯定他們正在同時編輯?請記住,數據庫時間非常非常非常非常精確,因此您不會碰到記錄鎖。他們還會在嘗試再次進行交易之前讓其中一個進程等待一段時間。 – Limey 2011-06-01 14:35:30

+0

就像一個建議和良好的編程practive,從來沒有'SELECT *'。列出你需要的所有列名,即使它是整個表。你永遠不知道這個表何時會被另一個開發者修改。 – JonH 2011-06-01 14:45:35

回答

0

如果您使用的是MS SQL您需要查看NOLOCKROWLOCK NOLOCK告訴SQL Server忽略任何類型的鎖並直接從實際表中讀取。親是它有很好的表現,這樣你就可以繞過一個鎖定的系統。另一方面,ROWLOCK要求SQL Server使用行級鎖。性能確實與ROWLOCK阻礙,所以你需要確定是否需要對UPDATES/DELETES

鎖定在你的情況SELECT isOriginal, * FROM myTable WITH (NOLOCK) WHERE tnr=x

然後UPDATE myTable WITH (ROWLOCK) SET is_active=0 WHERE tnr=x

0

不知道什麼數據庫使用的是你可以設置一個鎖場在分貝。

其中每個併發線程都有一個PID或線程ID或至少一種獨特的時間戳 一個

update myTable set lock = <pid> where pid = null limit 1; 

select isOriginal, * from myTable where lock = <pid>