如何悲观锁然后无限期地持有以跟踪谁是集群中的主人?

Posted

技术标签:

【中文标题】如何悲观锁然后无限期地持有以跟踪谁是集群中的主人?【英文标题】:How to Pessimistic lock then hold indefinitely in order to track who's master in a cluster? 【发布时间】:2014-09-02 21:11:03 【问题描述】:

我认为这真的很简单,但到目前为止我还没有做到这一点。我有一个 tomcat 集群,我想分配一个 master。

我正在考虑节点之间的竞赛以锁定表。谁锁定它就是主人。主人现在必须保留那个锁。其他节点应该尝试获取锁...

我不介意纯 JDBC,但应用程序使用 JPA 和 EJB (TomEE)

如何锁定? 如何保持锁定? 如果已经锁定,如何无限期地等待获取锁定?

好吧,我设法让它“永远等待”,但现在我很害怕,因为在阅读文档时,我觉得它根本不应该等待,所以我觉得我无法控制......

这是我使用 Eclipselink 的死锁:

    Map<String, Object> timeout = new HashMap<>();
    timeout.put("javax.persistence.lock.timeout", 1L);
    master = entityManager.find(Master.class, "MASTER", LockModeType.PESSIMISTIC_READ, timeout);

超时标志也在persistence.xml中指定...

【问题讨论】:

forums.terracotta.org/forums/posts/list/4349.page 【参考方案1】:

要获得锁,请使用javax.persistence.LockModeType.PESSIMISTIC_WRITEEntityModelock() 方法(或任何采用锁定模式的方法)。您可以通过不让事务完成(通过提交或回滚)来保持锁定。

为了继续重试锁定,我会使用 try-catch 永远循环以处理发生的异常并再次尝试获取锁定。请注意,根据您的隔离级别,您可能必须在每次尝试获取锁时清理旧事务并启动新事务。将您的锁定等待超时设置为合理的持续时间(例如一分钟)或Thread.sleep() 至少在两次尝试获得锁定之间短暂,这样您就不会浪费大量资源尝试和未能获得所有非锁定主服务器。

您需要确保没有任何超时会过早终止连接或事务(对于“主”和所有试图成为主的非主)。

您还需要确保以自动方式正确处理“主”更改(最终会发生),因此当另一台服务器设法获得锁定时,它会接管所有“主”业务逻辑。

【讨论】:

这就是我的想法 :-) 问题是 PESSIMISTIC_WRITE 和 PESSIMISTIC_READ 似乎都对读取行没有影响。但是,当我使用 PESSIMISTIC_WRITE 并尝试更新行时,我遇到了 Eclipselink 的死锁。我尝试设置: 但它没有帮助。如果甚至阻止读取,我也更愿意...... 确定我做错了什么。现在它在读取时死锁。但是我不明白为什么它不抛出异常而不是死锁。查看更新的问题 我将创建新问题

以上是关于如何悲观锁然后无限期地持有以跟踪谁是集群中的主人?的主要内容,如果未能解决你的问题,请参考以下文章

什么是乐观锁和悲观锁?

什么是乐观锁和悲观锁?

AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念

乐观锁和悲观锁

Java 锁机制总结

确保释放悲观锁