gpt4 book ai didi

java - 单个线程中的单个 hibernate session 导致死锁

转载 作者:行者123 更新时间:2023-11-29 09:10:45 26 4
gpt4 key购买 nike

我正在尝试为使用 hibernate 的 Java 服务器中的竞争条件设置一个临时解决方法。代码最初看起来像这样:

s = sessionFactory.openSession();
Object o1 = dao.getMostRecentVersionOfObject(key, s);
if (o1.performSomeTimeConsumingTask() == Looks.Ok) {
Transaction t = s.beginTransaction();
dao.update(o1, s);
t.commit();
}

最初的问题是,如果 2 个不同的线程大致同时访问同一代码块,它们都会尝试获取相同版本的对象,因此第二个线程总是会失败。由于有多个负载平衡的服务器,这个问题的真正解决方案是使用分布式锁定系统来确保版本保持同步并且事务不会相互干扰。然而,由于用户已经发现这是一个问题,而且这个问题的长期解决方案需要时间来开发,我做出了执行决定,通过检查对象是否已在交易前更新来添加一个临时 hack开始。我创建了第二个 session 来执行此版本检查。如果有更新,我会使用第二个 session 来填充对象的字段,然后保存它。所以新代码看起来有点像这样:

Session s = sessionFactory.openSession();
Session transactionSession = s;
Object o1 = dao.getMostRecentVersionOfObject(key, s);
int version = o1.getVersion();
if (o1.performSomeTimeConsumingTask() == Looks.Ok) {
Session newerSession = sessionFactory.openSession();
Object newerObject = dao.getMostRecentVersionOfObject(key, newerSession);
if (newerObject.getVersion() > version) {
// update fields...
transactionSession = newSession;
}
}
Transaction t = transactionSession.beginTransaction();
dao.update(o1, transactionSession);
t.commit();

此代码可在多种环境中运行,但由于已报告的死锁而无法在最重要的环境中运行。当甚至没有对该方法的第二个并发请求时,就会发生这种情况——第二个 session 被创建,检查版本,然后在第一个 session 执行提交事务时被忽略。我怀疑这个问题要么是环境问题(但我不明白为什么会这样),要么是 hibernate 不喜欢使用第二个 session ,但这只是一个有根据的猜测。我特别困惑为什么 hibernate 会将此报告为死锁,因为只有一个事务。

非常感谢任何关于此的想法!

最佳答案

The original problem is that if 2 different threads get to the same block of code at roughly the same time, they will both try and get the same version of the object, so the second one will always fail.

你的第二个解决方案仍然有同样的问题。你这样做,

  1. 获取最新对象
  2. 如果版本不同则更新字段
  3. 提交更新的对象

当您执行第 2 步时,其他线程会更新该对象。

如果你想防止这种情况发生,请同步方法(最不推荐)或执行以下操作,

Session s = sessionFactory.openSession();
Object o1 =s.get('o1s class',key,new LockOptions(LockMode.PESSIMISTIC_WRITE));
//Do whatever you want with o1
//Update o1
//commit

想法是通过从 db 获取更新锁来获取对象。参见 doc .您应该了解使用悲观锁定相对于乐观锁定的优缺点。

关于java - 单个线程中的单个 hibernate session 导致死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12588581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com