我有通过WCF MSMQ传输公开的服务。如何基于密钥同步一段代码?
此服务所做的一部分工作是查找基于某个键(source,item_id)的项目。 如果它找到一个,它将检索数据库标识并使用它来更新记录。 如果它没有找到,它会插入新记录。
我注意到两个项目可能同时进来,都看到一个项目不存在于数据库中,它们都尝试插入,但是一个失败并出现约束错误。
我想限制对数据库查找和基于密钥(源,item_id)的代码的访问权限,以便一次只有一个线程可以为该特定密钥执行工作。
我已经把一些代码放在一起做到这一点,但我想获得一些反馈,如果这个工作或者如果有更好的方法。
代码使用LockManager
类:
public class ItemService
{
private static LockManager lockManager = new LockManager();
public void AddItem(Item item){
var itemKey = item.Source + ":" + item.ItemId;
lockManager.Work(itemKey, delegate(){ do stuff });
}
}
LockManager
类:
public class LockManager
{
private readonly IDictionary<string, LockObject> _lockTable =
new Dictionary<string, LockObject>();
public void Work(string key, Action work)
{
var lockObject = BorrowLockObject(key);
try
{
lock (lockObject)
{
work();
}
}
finally
{
ReturnLockObject(lockObject);
}
}
private LockObject BorrowLockObject(string key)
{
lock (_lockTable)
{
LockObject lockObject = null;
if (_lockTable.ContainsKey(key))
{
lockObject = _lockTable[key];
}
else
{
lockObject = new LockObject(key);
_lockTable[key] = lockObject;
}
lockObject.Open();
return lockObject;
}
}
private void ReturnLockObject(LockObject lockObject)
{
lock (_lockTable)
{
if (lockObject.Close())
{
_lockTable.Remove(lockObject.GetKey());
}
}
}
}
LockObject
类:
public class LockObject
{
private readonly string _key;
private int _count;
public LockObject(string key)
{
_key = key;
_count = 0;
}
public string GetKey()
{
return _key;
}
public void Open()
{
lock(this)
{
_count++;
}
}
/// <summary>
/// Closes this lock object.
/// </summary>
/// <returns>True if this Lock Object is no longer in use.</returns>
public bool Close()
{
lock(this)
{
_count--;
return _count == 0;
}
}
}
我想我也可以通过我的dao调用使用事务来解决这个问题。我只需要使用适当的事务隔离。这可能是一个比上面的锁管理器更好的解决方案。 – ScArcher2 2011-05-31 16:25:59