The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

ari.meyer (2) [Avatar] Offline
#1
Hi,

I have the seemingly simple case wherein I want to log messages to a database. As you say in 6.1 Understanding transactions [REQUIRES_NEW]:

"You should use it if you need a transaction but don’t want a rollback to affect the client. Also use this value when you don’t want the client’s rollback to affect you. Logging is a great example. Even if the parent transaction rolls back, you want to be able to record the failure in your logs. On the other hand, failing to log a minor debugging message should not roll back your entire transaction and the problem should be localized to the logging component."

So I've tried using REQUIRES_NEW, but when invoked from an enclosing transaction, this results in an apparent database deadlock, and my app hangs. I assumed, somewhat naively, that txn A would be suspended while txn B executes, then control would return to A, but this is obviously incorrect. I then found this: http://java.sys-con.com/node/204688?page=0,1 ("Deadlocks in J2EE"), wherein the "Cross-Resource Deadlock #2: Single-Thread, Multiple Conflicting Database Connections" describes my issue.

So how can write my LoggingService using REQUIRES_NEW (assuming proper transaction suspension), and consistently avoid deadlocks? As it stands, I have to restrict usage to only places outside of an enclosing transaction, which makes LoggingService no longer a service that can be used anywhere, without further consideration.

I am now considering changing the implementation to use JMS (or perhaps even just start another thread), hoping that this would effectively decouple the 2 transactions. Is this an appropriate approach, even though it seems overkill? How can you implement this, as you described, and ensure that deadlocks will be avoided?

Thanks,
Ari

Message was edited by:
ari.meyer