【问题标题】:Hibernate Duplicate Entry exception creates Lock on row in MySQLHibernate Duplicate Entry 异常在 MySQL 中的行上创建锁定
【发布时间】:2015-03-30 20:14:34
【问题描述】:

使用 MySQL 和 Hibernate 4.3.5

我在Mortgage 表中有一行,主键为091210。在使用休眠的 Java 应用程序中,当我(错误地)尝试使用相同的密钥保存抵押时,会记录正确的 com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '091210' for key 'PRIMARY' 异常,不抛出

问题:

抛出/记录此异常,但程序未完成执行或终止。此外,我注意到在导致重复异常的原始行上创建了更新/删除锁。恢复的唯一方法是如果我可以手动终止程序,然后原始行不再“锁定”

  • 这是预期的,有没有人经历过这种情况?
  • 如何在 Java 程序中恢复?

我希望这种异常会取消/中断事务,然后抛出异常。但是相反,似乎只记录了异常,在 DB 上创建了一个锁,并且该进程似乎只是挂在 transaction.commit()...

代码:

System.out.println("Begin transaction");
session.beginTransaction();

System.out.println("Save mortgage");
session.save(mortgage);
System.out.println("Commit transaction");
session.getTransaction().commit();

System.out.println("Close session");
session.close();
System.out.println("Close SessionFactory");
HibernateUtil.getSessionFactory().close();

我看到的相关输出:

Begin transaction
Save mortgage
Commit transaction
Hibernate: insert into mortgage (address, last_name, inst_id, date, mortgage_num) values (?, ?, ?, ?, ?)
Mar 30, 2015 7:59:54 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions

... Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '091210' for key 'PRIMARY'

然后程序就挂了,仍然运行,红灯发光,并且数据库上的锁。

没有try-catch,没有日志记录。这是来自 Eclipse 控制台。

【问题讨论】:

  • 我假设您捕获了异常,然后将其写入日志文件。当你捕捉到它时,你会回滚休眠事务吗?因为那应该可以修复锁。
  • 我的应用没有做任何日志记录,也没有try-catch。我将使用我执行的代码更新答案。
  • 好的,我明天上班再研究一下,如果我能找到 15 分钟左右的空闲时间。
  • 帮帮我@Ractoc,你是我唯一的希望;)

标签: java mysql hibernate database-deadlocks


【解决方案1】:

让我把答案放在这里,以便我可以正确格式化代码...

在您的代码中,添加一些错误处理:

try {
    System.out.println("Begin transaction");
    session.beginTransaction();

    System.out.println("Save mortgage");
    session.save(mortgage);
    System.out.println("Commit transaction");
    session.getTransaction().commit();

    System.out.println("Close session");
    session.close();
    System.out.println("Close SessionFactory");
    HibernateUtil.getSessionFactory().close();
} catch (HibernateException he) {
    he.printStackTrace();
}

这会将整个堆栈跟踪打印到您的控制台。有更好的方法来记录这样的东西,但这样做不会很好。当您最终陷入困境时,您可能还想很好地回滚事务。但是,在我们解决了您更紧迫的问题之后,可以进行这种清理。

如果你愿意,我会在接下来的几天里提供一个很好的教程。

【讨论】:

  • 如上面 Q 中提到的,没有任何异常。这就是为什么这很奇怪。没有异常被抛出/捕获。程序就挂在那里了。我没有任何 catch 语句,所以抛出的任何东西都应该终止程序。来自hibernate的日志显示不是因为我正在做任何日志记录,而是因为Eclipse只是将hibernate自己的日志记录到控制台窗口
猜你喜欢
  • 2017-09-05
  • 2015-05-14
  • 2015-10-08
  • 2022-11-03
  • 2021-08-06
  • 2016-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多