如何对 Java EE 数据库审计记录器进行多线程处理?
我正在开发一个在 Websphere 7.0 上运行的 Java EE 5 应用程序,并试图找到一种线程安全且高性能的方法来多线程数据库审核日志记录的持久性。 是否有任何已知的方法可以在 Java EE 应用程序中安全高效地执行多线程审核日志记录?
如果您需要一些背景信息:该应用程序是一个 Web 服务,它收到的每个请求消息都会产生结果创建 100 或 200 条审核日志消息,这些消息必须持久保存到数据库中。最初,审计日志记录是使用扩展 java.util.logging.Handler 的自定义审计处理程序类完成的,并且发布方法将打开数据库连接,从 LogRecord 填充准备好的语句,并执行插入。由于此自定义处理程序在 EJB 线程内运行,因此审核日志记录可能会导致每个请求消息的响应时间增加几秒,并导致错过 SLA。
因此,审计处理程序被替换为一个包装处理程序,该处理程序添加了创建一个单独的线程(是的,使用 new Thread(),违反了 Java EE 的规则)。包装处理程序使用 Vector 对审核记录进行排队,并使用审核处理程序将它们尽可能快地保存在单独的线程中。
虽然它打破了 Java EE 线程的规则,但这个包装器工作得很好......直到我们允许在 MDB 上并发调用。当允许多个 EJB 调用时,包装器有可能会出错,并且可能会将每个日志记录多次保存到数据库中。这似乎表明包装器或线程创建逻辑存在错误。
我本来打算努力找出并解决这个问题,但我想我首先要问一下是否有更好的方法。
I'm working on a Java EE 5 application running on Websphere 7.0, and am trying to find a thread-safe and performant way to multi-thread the persistence of database audit log records. Are there any known methods for performing multi-threaded audit logging safely and efficiently within a Java EE application?
If you need some background information: the app is a web service, and each request message that it receives results in the creation of 100 or 200 audit log messages which must be persisted to a database. Originally the audit logging was done with a custom audit handler class that extends java.util.logging.Handler, and the publish method would open a database connection, populate a prepared statement from the LogRecord, and execute the insert. Since this custom Handler was running within the EJB's thread, audit logging could add up to several seconds to the response time for each request message and was causing SLAs to be missed.
So the audit handler was replaced with a wrapper handler that adds creates a separate thread (yes, with new Thread(), against the rules of Java EE). The wrapper handler uses a Vector to queue the audit records, and it persists them as fast as possible in the separate thread using the audit handler.
While it breaks the rules of Java EE threading, this wrapper has worked quite well... until we allowed concurrent invocations on the MDB. The wrapper has the potential to screw up when multiple EJB invocations are allowed, and potentially will save each log record to the database multiple times. This seems to indicate that the wrapper or thread creation logic has a bug.
I was going to work on identifying and fixing that problem, but thought I'd first ask SO if there's a better way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 JMS,将这些审核消息放入队列中,然后调用其他一些服务来获取它们并将它们存储在数据库中。当然,这意味着所有日志不一定都实时存储在数据库中,但这种方法将从 Websphere 卸载一些工作,并且您的代码中不会有破坏标准的多线程。
Using JMS, put those audit messages on a queue, and then invoke some other service that will pick them up and store them in database. This, of course, means that all logs won't necessarily be stored in database in real time, but this approach will offload some work from Websphere and you won't have standard breaking multi threading in your code.