假设我有两个hazelcast节点,它们没有保证同步的系统时间(不要问我为什么要这样做,这只是一个假设问题):
假设节点1在开始时将其绝对时间设置为0 (System.currentTimeMillis返回0),节点2将其绝对时间设置为1000。
我创建了一个存储在节点1上的锁,并将其过期时间设置为100毫秒。它在节点1绝对时间100和节点2绝对时间1100期满。现在节点2加入了集群。我还检索了在节点2上运行的应用程序中的锁(当然不会尝试锁定它,因为它仍然锁定在节点1上)。现在,我持有对锁的两个ILock引用,一个在节点1上运行的应用程序中,另一个在节点2上运行的应用程序中。
当我在节点2上的ILock上调用操作时,它看到实际的对象(在锁存储中)位于节点1上,因此它远程调用节点1上的操作。如果我们等待100毫秒,节点1将使锁过期。
但我们不能等待。相反,我们关闭了节点1。锁被转移到节点2,因为节点1不再可用。在传输期间,节点1上的LockResourceImpl.writeData方法将锁的数据写入某个缓冲区。然后,这个缓冲区被转移到节点2,LockResourceImpl.readData方法在那里读取它,并在其自身上设置值。
据我所知,时间戳只是复制到相应的字段中,而没有考虑到节点2上的时钟可能不同。这意味着过期时间仍然是100 (节点1设置的绝对时间),而节点2的系统时间已经是1000。这意味着锁立即过期,尽管它不应该过期。
我的理解正确吗?这真的是一个问题吗?
发布于 2014-10-31 01:26:37
不,这不是问题。当节点死亡时,立即释放该节点所拥有锁是标准行为。如果你仔细想想,这是有道理的,因为死节点没有锁的用处,如果你通过在不同的机器上使用锁来强制定时等待,那么你的代码确实有问题。
免责声明:我没有调查过这个问题,但所描述的行为是集群(包括hazelcast)系统上锁定的标准行为。
https://stackoverflow.com/questions/26483185
复制相似问题