views:

109

answers:

4

Hey, Is there any way to "replay" transaction? I mean, sometimes I get RollbackException and rollback the transaction. Can I then "clone" the transaction and try again, or once rollback is called, transaction is lost? I really need the changes, and really don't want to trace every change for rerunning later...

thanks, udi

A: 

Just recall the same DAO class/method?

BalusC
A: 

Why do you get the exception in the first place ? This seems to me to be the crux of the matter.

Are you relying on optimistic writing ? If so, then you'll have to wrap your database writes in some form of loop, incorporating (perhaps) a backoff and a number of retries. You can't do this automatically, unfortunately (unless you investigate some form of AOP solution wrapping your database writes with a retry strategy ?)

Brian Agnew
A: 

That depends where that transaction comes from. In Java/JDBC, a transaction is tied to a connection. You start one by setting setAutoCommit() to false (otherwise, every statement becomes its own little transaction).

There is nothing preventing you from reusing the connection after a transaction failed (i.e. you called rollback).

Things get more tricky when you use Spring. Spring wraps your methods in a transaction handler and this handler tries to guess what it should do with the current transaction from the exceptions that get thrown in the method. The next question is: Which wrapper created the current transaction? I just had a case where I would call a method foo() which would in turn call bar(), both @Transactional.

I wanted to catch errors from bar() in foo() and save them into the DB. That didn't work because the transaction was created for foo() (so I was still in a transaction which Spring thought broken by the exception in bar()) and it wouldn't let me save the error.

The solution was to create baz(), make it @Transactional(propagation=Propagation.REQUIRES_NEW) and call it from foo(). baz() would get a new, fresh transaction and would be able to write to the DB even though it was called from foo() which already had a (broken) transaction.

Aaron Digulla
A: 

Another alternative is to use JDBC savepoints to partly roll back.

mhaller
As far as I understand, the savepoing doesn't help in this specific case, cause rolling back to the last savepoint does not preserve the data updated later..
Udi