考虑序列值是一个自定义自动增量键字母和数字组合特定的客户端需要他的系统。
我们做了一个名为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