【发布时间】:2016-05-18 15:51:01
【问题描述】:
在我的代码中,我有一种方法可以将资金从一个帐户转移到另一个帐户。显然,这种方法必须确保在程序执行的任何给定时刻,每个帐户只执行一个事务。我已经使用 2 个嵌套锁实现了这个检查(Account 是一个具有唯一整数 ID 的数据库实体):
public void Transfer(Account from, Account to, decimal amount)
{
lock(GetLockObject(from))
{
lock(GetLockObject(to))
{
DoTransfer(from, to, amount);
}
}
}
private static Dictionary<int, object> lockObjects = new Dictionary<int, object>();
private static GetLockObject(Accont acc)
{
lock (lockObjects)
{
var lockObject = lockObjects[acc.Id];
if (lockObject == null)
{
lockObject = new object();
lockObjects[accId] = lockObject;
}
return lockObject;
}
}
这似乎工作正常,但我有两个问题:
- 如果使用相同的 2 个帐户作为其参数同时调用该方法,则代码可能会导致死锁:
Transfer(acc1, acc2, 10);Transfer(acc2, acc1, 10);如何避免死锁? - 能否以比使用嵌套锁更好的方式(在性能、可靠性等方面)实现相同的结果?
【问题讨论】:
标签: c# concurrency locking