I have a question about how @Transactional annotation alone manages code and transactions execution. Given a correctly setup Spring application and the following code:
@Transactional
public void withdraw(int amount) {
if(isEnoughFunds(amount)) {
decreaseFunds(amount);
}
}
Is it possible for the following scenario to occur:
If this is possible how would you prevent that?
Spring uses the underlying database implementation for transactions, so they are as thread safe as the underlying database can be. Transaction isolation is a different issue from thread-safety.
The @Transactional annotation is the metadata that specifies the semantics of the transactions on a method. We have two ways to rollback a transaction: declarative and programmatic. In the declarative approach, we annotate the methods with the @Transactional annotation.
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings.
The usage of the @Repository annotation or @Transactional . @Repository is not needed at all as the interface you declare will be backed by a proxy the Spring Data infrastructure creates and activates exception translation for anyway.
Yes, it is possible, depending on the isolation level. To prevent it, you can explicitly obtain a read lock from the database before calling ifEnoughFunds(). The lock will be released at the end of the transaction. In this scenario, thread B will always wait for thread's A transaction to commit before checking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With