views:

237

answers:

2

I am working on a program that uses Spring and obtains Hibernate transactions transparently using a TransactionInterceptor. This makes it very convenient to say "when this method is invoked from some other class, wrap it in a transaction if it's not already in one."

However, I have a class that needs to attempt a write and must find out immediately whether or not it has succeeded. While I want two methods anyway, I was hoping that there was a way to keep them in the same class without needing to explicitly create an transaction procedurally. In effect, I'd like something like this:

public void methodOne() {
    //..do some stuff
    try  {
       transactionalMethod();//won't do what I want
    } catch(OptimisticLockingFailure e) {
      //..recover
    }
}

@Transactional
public void transactionalMethod() {
    //...do some stuff to database
}

Unfortunately, as I understand it, this wouldn't work because I'd just be directly calling transactionalMethod. Is there a way to ask Spring to call a local method for me and wrap it in a transaction if needed, or does it have to be in another class that I wire to this one?

+1  A: 

Define an interface which the class implements which does the transactionalMethod(); use dependency injection to set the class' value of that to its own implementation; in your bean factory, allow Spring to insert an Around aspect around that interface implementation. That should work for your needs.

McWafflestix
A: 

If you want the transactionalMethod to be part of it's own transaction and not simply join onto the transaction that is already active you have to set the propagation to REQUIRES_NEW. Like so

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void transactionalMethod() {
    //...do some stuff to database
}

You should also check that your transaction manager supports this propagation. the means that transactionalMethos is completely seperate from the other transaction that it was called from and it will commit / rollback completely seperately as well.

mR_fr0g