Damian
Damian

Reputation: 21

Is it possible to not be in @Transaction state, when calling a function from a transacted function?

Not sure how to word the title but I'm using Spring boot, and I have a function like:

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
    public Optional<List<SomeClass>> bulkInsert(List<SomeClass> models, boolean withRefresh) {
        int rowsInserted = someDao.bulkInsert(models).length;
        if (rowsInserted > 0 && withRefresh) {
            // I don't want the getLatest() function to operate in a transaction
            return Optional.of(getLatest(someValue, models.size())); 
        }
        return Optional.empty();
    };

    @Transactional(propagation = NOT_SUPPORTED)
    public List<SomeClass> getLatest(long someValue, int limit) {
        TransactionStatus status = TransactionAspectSupport.currentTransactionStatus(); ### says the transaction is active
        return someDao.getLatest(accountId, limit);
    };

Basically I want to exclude the getLatest() from the transaction. Is it possible?

Upvotes: 0

Views: 83

Answers (2)

cool
cool

Reputation: 1786

If you want to use transaction only for

someDao.bulkInsert(models).length;

then you should wrap this code with transactional aspect and call the other part separately. Like this:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
public int bulkInsert(List<SomeClass> models, boolean withRefresh) {
   return  someDao.bulkInsert(models).length;
}

public Optional<List<SomeClass>> abc(int rowInserted, boolean withRefresh){
    if (rowsInserted > 0 && withRefresh) {
       return Optional.of(getLatest(someValue, models.size())); ### I don't want the getLatest() function to operate in a transaction
    }

    return Optional.empty();
} 

public List<SomeClass> getLatest(long someValue, int limit) {
  TransactionStatus status = TransactionAspectSupport.currentTransactionStatus(); ### says the transaction is active
  return someDao.getLatest(accountId, limit);
};

Most importantly you need to call this method from outside of this instance.

For the question you have in the title: No you can't take some piece of the code outside of the transaction because spring-aop uses proxies and the whole method is wrapped with transactional aspect in the proxy instance.

Upvotes: 1

Robert Wynkoop
Robert Wynkoop

Reputation: 43

Use this instead:

 @Transactional(propagation = NOT_SUPPORTED)
    public List<SomeClass> getLatest(long someValue, int limit) {

See Spring Propagation Doc for explanation of propagation levels.

Upvotes: 1

Related Questions