javaspringspring-transactionsaspects

Spring: Adding Transaction Specific Resource


I am trying to find a way to add/get a resource/state to an existing transaction. Is this possible in Spring?

What I'm trying to achieve is similar to the pseudo code below:

@Service
@Transactional("txManager")
public class ServiceImpl implements Service {

    @Override
    @AddResourceHere
    public TestObj doSomething(){
        ...
    }

    @Override
    @AddResourceHere
    public TestObj doSomethingAgain(){
        ...
    }
}

@Aspect
@Component
public class Interceptor {

    private static final Logger logger = LogManager.get(Interceptor.class);

    @Before("@annotation(my.package.AddResourceHere)")
    public void switchDatabase(JoinPoint joinPoint){
        MyResource resource = TransactionResouceAdder.getResource("transactionSpecificResource");
        if(resource == null){
            TransactionResouceAdder.addResource(new MyResource("A new resource"));
            ...
        }

        else
            log.info("resource has already been added for this transaction");
    }
}

public class Test {
    ...
    @Test
    @Transactional("txManager")
    public void doSomethingTest(){
        serviceImpl.doSomething();
        serviceImpl.doSomethingAgain();
    }
}

I found something similar

org.springframework.transaction.support.TransactionSynchronizationManager#getResouce(Object)
org.springframework.transaction.support.TransactionSynchronizationManager#bindResource(Object, Object)

However, this adds a resource to the current thread of the transaction. Is there a way to make the resource transaction bounded only?

In my actual code, I am using spring jdbc's DataSourceTransactionManager as the transaction manager.

Thanks in advance for any help :)


Solution

  • TransactionSynchronizationManager was designed for this purpose and resources are cleared at the end of a transaction (see AbstractPlatformTransactionManager). You'd have to hook it up to your custom annotation with an aspect, but it looks like you already know how to do that.