免责声明:我已经问过this question,但没有 部署要求。我有一个 答案得到3个赞成票,当我 编辑了问题以包含部署要求的答案 变得无关紧要。我之所以如此 重新提交是因为SO考虑 原来的问题“回答”,甚至 虽然我没有得到任何有意义的投票 回答。我打开了一个关于这个问题的uservoice submission。 我转发的原因是StackOverflow认为原始问题已经回答,所以它没有出现在“未答复的问题”标签上。
您将使用哪种分布式锁定服务?
要求是:
我对“它可以在数据库上完成”或“它可以在JavaSpaces上完成”等答案不感兴趣 - 我知道。相关答案应该只包含一个现成的,开箱即用的,经过验证的实现。
答案 0 :(得分:4)
您的.Net实现与Java API提供的现有开箱即用锁定/解锁API非常接近。看到: http://www.gigaspaces.com/docs/JavaDoc8.0/org/openspaces/core/DefaultGigaMap.html
您可能会将此Java类的源代码作为产品随附的gs-openspaces-src.zip文件的一部分找到。与Gigaspaces .Net API相同应该是直接的。
答案 1 :(得分:1)
以下是基于GigaSpaces的答案的大纲,它符合您的标准,具体取决于您在标准3中的含义。我使用.Net的GigaSpaces,而不是Java:
创建一个带有SpaceID + SpaceRouting属性的锁定类,用于标识锁定的内容和DataMember bool属性Unlocked:
sealed public class IdLockTrans
{
[SpaceID]
[SpaceRouting]
public string ID
{
get;
set;
}
[DataMember]
public bool Unlocked
{
get;
set;
}
public IdLockTrans(Id id)
{
ID = id.ID;
}
public IdLockTrans()
{
}
}
您将使用GigaSpaces的租约时间进行锁定释放 超时。这将导致GigaSpaces删除IdLockTrans对象 在空闲超时后自动从空间开始 期。缺少IDL的IdLockTrans意味着ID已解锁。
您的更衣室课程将定义并初始化这些班级成员
private readonly ISpaceProxy _proxy;
private readonly long _leaseTime;
public override bool Lock(Id id, long timeout)
{
bool locked;
IdLockTrans lockTransTemplate = new IdLockTrans(id);
// Assume that this is a new id.
try
{
_proxy.Write(lockTransTemplate, null, _leaseTime, 0, UpdateModifiers.WriteOnly);
locked = true;
}
catch (EntryAlreadyInSpaceException)
{
using (ITransaction tx = _proxy.CreateLocalTransaction())
{
try
{
lockTransTemplate.Unlocked = true;
IdLockTrans lockTrans = _proxy.Take(lockTransTemplate, tx, timeout);
locked = (lockTrans != null);
if (lockTrans != null)
{
lockTrans.Unlocked = false;
_proxy.Write(lockTrans, tx, _leaseTime, 0, UpdateModifiers.WriteOnly);
}
tx.Commit();
}
catch
{
tx.Abort();
throw;
}
}
}
return locked;
}
public override void Unlock(Id lockedId)
{
IdLockTrans lockTrans = new IdLockTrans(lockedId);
lockTrans.Unlocked = true;
try
{
_proxy.Update(lockTrans, null, _leaseTime, 0, UpdateModifiers.UpdateOnly);
}
catch (EntryNotInSpaceException)
{
throw new Exception("IdLockTrans for " + lockTrans.ID
+ " not found on Unlock. Lock time exceeded lease time.");
}
}
答案 2 :(得分:0)
如果您还在寻找,请查看Apache Zookeeper:
ZooKeeper是一种集中式服务,用于维护配置信息,命名,提供分布式同步和提供组服务。所有这些类型的服务都以分布式应用程序的某种形式使用。
Zookeeper文档在Zookeeper上提供了how to build a Lock service的示例。
答案 3 :(得分:0)
使用mysql锁定唯一键非常简单。
假设1:
您使用事务并且您的隔离级别被读取已提交。
假设2: 您通过唯一键锁定处理线程,并在提交事务时释放它。
然后你可以使用这个sql作为分发锁:
插入distributed_lock(密钥) 值(#{key})ON DUPLICATE KEY UPDATE key = key;