【问题标题】:Mysql/JDBC: DeadlockMysql/JDBC:死锁
【发布时间】:2015-08-04 06:31:06
【问题描述】:

我有一个 J2EE 服务器,目前只运行一个线程(即使在一个请求中也会出现问题)以将其内部数据模型保存到 MySQL/INNODB 表。

基本思想是从平面文件中读取数据,进行大量计算,然后将结果写入 MySQL。第二天读取另一组平面文件并重复步骤 1。由于只有一小部分行更改,我使用已写入行的记录集,与内存中的当前结果进行比较,然后相应地更新/插入它(没有删除,只是设置一个deletedFlag)。

问题:尽管是一个纯粹的顺序过程,但我得到了锁超时错误 (#1204) 并且 Innodump 显示记录锁(虽然我不知道如何计算细节)。为了使我的 Windows 机器下的事情复杂化,一切正常,而生产系统(我无法安装 innotop)有一些记录锁。

到关键代码:

  1. 读取数据并计算(有效)
  2. 从 Tomcat 池获取连接并设置为 autocommit=false
  3. 使用语句发出“LOCK TABLES order WRITE”
  4. 按表顺序打开记录集(可更新)
  5. 对于 Recordset 中的每一行 --> 如果有差异,则从内存对象更新
  6. 对于尚未在数据库中的对象 --> 插入数据
  7. 提交连接,关闭连接

步骤 5/6 有一个 Commitcounter,因此每 500 次更改都会提交行(以避免有 50.000 行未提交)。在第一次运行(所以没有任何锁)这需要最大。 30秒/桌。

如上所述,我现在避免与数据库进行任何其他交互,但将来其他进程(用户请求)可能会读取数据甚至写入一些字段。我不介意这些进程读取旧/新数据并等待几分钟以将更改保存到数据库(即锁定)。

我很乐意接受任何比这更好的建议。

总结:复杂代码计算要与数据库同步的内存对象。尽管事实上它顺序锁定,但这种同步当前似乎锁定了自己,更改解锁表而没有抛出任何异常。但由于某种原因,行锁似乎仍然存在。

亲切的问候

附加信息: Mysql:show processlist 列出没有活动的连接(全部休眠或等待表顺序上的表锁),而“show engine INNODB”报告了许多行锁(不幸的是我不明白哪个事务是指输出非常神秘) .

【问题讨论】:

  • 你使用的是纯 jdbc 吗?没有代码使检查变得更加困难。您是否在每次写入时都提交并关闭连接?您是否在不需要时保持连接打开?
  • 抱歉这么晚才回来。我通过标准 Tomcat 连接池(通过 web.xml 中的 ressource-defs 配置)和 DataSource.getConnection 使用 JDBC。
  • 不要在 InnoDB 中使用 LOCK TABLE

标签: java mysql jdbc locking innodb


【解决方案1】:

已解决:我错误地将 ResultSet 声明为可更新。 ResultSet 仅通过垃圾收集器的“finalize()”方法关闭,速度不够快 - 在我重新打开 ResultSet 并因此尝试获取已锁定表上的锁之前。

然而奇怪的是,innotop 显示我的另一个查询挂在一个完全不同的表上。虽然它对我有用,但我不在乎奇怪:-)

【讨论】:

    猜你喜欢
    • 2018-07-27
    • 2016-08-22
    • 2011-07-16
    • 1970-01-01
    • 2013-01-29
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多