考慮序列值是一個自定義自動增量鍵字母和數字組合特定的客戶端需要他的系統。
我們做了一個名爲GetNextSequence()的函數,它應該返回序列的下一個值。步驟來讀取和更新程序進行如下
- 閱讀使用keyid的序列:
SELECT Sequence FROM [Key] WHERE KeyId = @Id
- 解析序列值,並確定下一個值
- 序列值寫入表:
UPDATE [Key] SET Sequence = @Sequence WHERE KeyId = @Id
下面是C#代碼(爲了清楚而簡化):
var transaction = connection.BeginTransaction(IsolationLevel.RepeatableRead);
var currentSequenceValue = SqlUtils.ExecuteScalar(connection, transaction, "SELECT Sequence FROM [Key] WHERE KeyId = @Id", new SqlParameter("@Id", keyId));
var updatedSequenceValue = ParseSequence(currentSequenceValue);
SqlUtils.ExecuteScalar(connection, transaction, "UPDATE [Key] SET Sequence = @Sequence WHERE KeyId = @Id", new SqlParameter("@Id", keyId), new SqlParameter("@Sequence", updatedSequenceValue));
transaction.Commit();
return updatedSequenceValue;
我們的問題駐留在兩個不同的服務器可以訪問相同的序列,我們最終得到死鎖
事務(進程ID X)被死鎖的鎖資源與另一個進程,並已被選作死鎖犧牲品。重新運行交易。
在C#中,我試圖建立不同的鎖組合就像使用表提示ROWLOCK
和HOLDLOCK
事務隔離IsolationLevel.RepeatableRead
或IsolationLevel.Serializable
或SQL,但沒有成功。
我希望每個服務器都能夠以原子方式讀取,操作和更新序列。爲這種情況設置鎖定的正確方法是什麼?
一邊注意這聽起來像這個問題:http://www.codinghorror.com/blog/2008/08/deadlocked.html – BrokenGlass