mysql 事务悲观锁损坏
我正在使用 hibernate、innodb 和 mysql。我在一个很长的休眠事务开始时获得了一个悲观锁(在特定的表行上)。有时,当我运行启动此事务的程序并在独立应用程序模式下在 Eclipse 中运行,并对应用程序进行硬停止(这会强制线程死亡)时,我会遇到以下情况:
MySQL 没有意识到该事务被中止。下次我运行我的应用程序时,获取悲观锁(在那个长事务开始时)的函数会阻塞,即使 MySQL 应该意识到该行已解锁。
让一切再次正常工作的唯一方法是停止 MySQL 守护进程并重新启动它,然后获得悲观锁。
这确实让我担心。这意味着除异常或干净关闭之外的任何 VM 退出都可能使 MySQL 处于损坏状态,需要重新启动 MySQL 守护程序。例如,使用正常方式关闭并重新启动 Tomcat,在我的理解中,这涉及线程死亡,就像使用 eclipse 中止正在运行的应用程序一样。
其他人遇到过这个问题吗?有没有一种干净的方法来停止tomcat而不涉及线程死亡?难道 MySQL 不应该在获得悲观锁(select for update)的事务中免受线程死亡的影响吗?
我正在使用 $CATALINA_HOME/bin/shutdown.sh 停止 tomcat
Andy
I am using hibernate, and innodb and mysql. I have a pessimistic lock (on a specific table row) obtained at the beginning of a very long hibernate transaction. On occasion, when I run the program that starts this transaction and am running in eclipse in standalone application mode, and do a hard stop of the application (which forces a threaddeath), I have the following scenario:
MySQL does not realize that the transaction was aborted. The next time I run my application, the function which obtains the pessimistic lock (at the beginning of that long transaction) blocks, even though MySQL should realize that that row is unlocked.
The only way to get things working again is to stop the MySQL daemon and restart it, after which the pessimistic lock is obtained.
This really concerns me. This means that any VM exit other than by exception or clean shutdown can leave MySQL in a broken state that requires restarting MySQL daemon. An e.g. is using the normal way to shutdown and restart Tomcat, which in my understanding involves a threaddeath, just like using eclipse to abort a running application.
Have other people encountered this problem? Is there a clean way to stop tomcat which does not involve threaddeath? Shouldn't MySQL be immune to threaddeath in the middle of a transaction that has obtained a pessimistic lock (select for update)?
I am stopping tomcat with $CATALINA_HOME/bin/shutdown.sh
Andy
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想说的是你没有等待足够的时间来触发交易超时。在任何数据库(尤其是 MySQL)中,您都可以指定事务超时,如果在此之前未提交事务,则该事务将回滚。
I'd say that you didn't wait enough to trigger the transaction timeout. In any database (and MySQL, for certain), you can specify a transaction timeout which will rollback the transaction if it's not committed before then.