有没有办法在Oracle异常上触发jvm线程转储?

时间:2011-10-24 02:18:58

标签: java oracle websphere deadlock

我们有一个在Websphere中运行的Java程序,并使用直接jdbc(没有Hibernate或JPA)的Oracle数据库。我们的客户正在使用HP Performance Center进行负载测试,并且他在负载下偶尔会遇到Oracle“死锁”异常

Caused by: java.sql.SQLException: ORA-00060: deadlock detected while waiting for resource

有没有办法,无论是在代码中还是从外部强制执行此异常发生时{j}给jvm时获得的相同类型的线程转储?

2 个答案:

答案 0 :(得分:7)

如果在异常发生时无法自动检测,那么知道如何枚举线程将没有多大用处。

我们一直这样做。我们基本上使用:

Thread.setDefaultUncaughtExceptionHandler

当我们的应用程序启动时,我们会在发生异常时转储我们想要的信息:

  • Map<Thread, StackTraceElement[]> mst = Thread.getAllStackTraces();

  • Runtime.getRuntime().freeMemory() / maxMemory() / totalMemory()获取基本内存信息

  • 用户使用模式,如果它是用户可以与之交互的应用

  • 自制“分析”

然后你可以调用很多其他东西并获得幻想。例如,我们会自动将崩溃报告(包括完整的堆栈跟踪)发送到等待此类跟踪的服务器。

答案 1 :(得分:1)

对于当前主题,您可以使用Thread.dumpStack()

对于所有线程,您可以使用Thread.enumerate()来获取所有正在运行的线程和dumpStack(),也可以使用Thread.getAllStackTraces()并将它们打印到控制台或您需要的任何位置。

为了在发生这些异常时发生这种情况,如果你不能在你自己的代码中执行此操作,你可以尝试AOP,编写代理(如果你使用的是Java 6+),或者你可以在紧要关头,获取SQLException的源代码,将其更改为在其构造函数中转储堆栈,重新编译并将此类放回引导类路径中,然后再执行其他操作。