我使用jboss 4.2.3。
它设置了“TransactionTimeout”(在jboss-service.xml中),它指定允许Transaction执行的时间。
不幸的是,当超时通过时,执行不会立即中止,如果事务正在执行某些操作,则只会将其标记为稍后回滚。
效果是 - 当我有持久的事务并且线程正在使用preparedStatement.execute时,例如,当TransactionTimeout通过时,没有任何事情发生,客户端仍然挂起,只有当preparedStatement完成时,才会出现事务被滚动的异常回来。
我尝试了来自http://management-platform.blogspot.com/2008/11/transaction-timeouts-and-ejb3jpa.html的拦截器但是它只将线程标记为中断,大多数方法在执行时都不会检查这个,所以效果是一样的。
我也尝试过设置preparedStatement.setQueryTimeout,但是在Oracle(我们使用)上,它等待中止会话直到oracle感觉就像这样做(例如它不会中止执行 dbms_lock的plsql过程。睡眠(..))。
我想杀死与事务关联的数据库会话,超时 - 我知道它是哪个事务,以及它与哪个线程关联(因为我使用上面给出的链接中的拦截器),但我不知道不知道如何获得事务绑定的会话 - 我必须得到它,杀掉它 - 然后线程将被中断。
我错过了更简单的解决方案,还是完全错误:)?
答案 0 :(得分:1)
我不知道这个答案是否有帮助,因为它在JDBC级别上,可能是由JBOSS提取的,但是试一试。
您可以使用Statement.cancel()方法取消运行JDBC语句,但行为依赖于DBMS和数据库驱动程序。据我所知,它应该适用于Oracle数据库。您必须从执行该语句的其他线程调用cancel语句。
答案 1 :(得分:1)
刚做了一些关于这个主题的研究。有一个JTA配置参数InterruptThreads,默认为false。阅读文档,这意味着线程不会被打断,只是标记为回滚,如你所说。
听起来像选项是: 1)将InterruptThreads(在jboss-service.xml中)设置为true和 2)还有一些关于定义自己的'CheckedAction'类的讨论,它包含在事务处理和终止过程中。
看起来使用默认设置,基本上允许线程到达某个点,它将回滚您的更新。
还有交易收割机配置,默认为2分钟 - 他们检查哪些交易可能已经超时 - 所以默认超时为5分钟,加上2分钟收割机 - 最坏的情况,假设您中断线程,你可以等7分钟。
答案 2 :(得分:0)
这似乎是What to do if user closes page in the middle of a mysql long query?的副本。这是相同的原则,除了服务器在完成之前结束它而不是客户端。
答案 3 :(得分:0)
我在我的一个项目中遇到了类似的问题。我使用Hibernate进行部署在JBoss 1.4.2和MySQL 1.5.x上的Web应用程序的数据库连接。
我使用innotop来监控长时间保持活跃的交易。为了管理这些交易,我构建了一个外部应用程序(我的是一个网络应用程序)运行
数据库上的显示进程列表
,它给出了每个用户执行的查询列表和时间 它跑了。其他详细信息包括queryId,用户,主机,数据库名称和状态
kill XXXX
命令。http://forums.oracle.com/forums/thread.jspa?threadID=906972在Oracle中显示类似内容。
这可能不是处理此的最理想方式。 我希望有一个更好的解决方案来处理更高级别的问题。如果需要应用程序的源代码,请告诉我。