Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when a @Transactional annotated method is hit in parallel by multiple instances?

Please correct me if I am wrong somewhere.

I am having an issue where my transaction are not being saved to the data base and some sort of racing is occurring which screws up the data. The app is hit in parallel by multiple instances. I have used @Transactional, which I know is to do a transaction with database and the transaction is committed when the method returns.

The question is, does hitting it through multiple instance still maintain this one transaction per hit thing, or it does not handle the situation and data will screw up because of racing?

Can a solution be suggested for the given condition?

like image 246
Nihal Sharma Avatar asked Feb 15 '14 22:02

Nihal Sharma


People also ask

What happens if one @transactional annotated method is calling another @transactional annotated method on the same object instance?

1 Answer. Show activity on this post. If you call method2() from method1() within the same class, the @Transactional annotation of the second method will not have any effect because it is not called through proxy, but directly.

What happens if a method annotated with @transactional calls another method annotated with transactional?

If you call a method with a @Transactional annotation from a method with @Transactional belonging to the same Spring Bean , then the called methods transactional behavior will not have any impact on the transaction.

What does the @transactional annotation do?

Transactional annotation provides the application the ability to declaratively control transaction boundaries on CDI managed beans, as well as classes defined as managed beans by the Java EE specification, at both the class and method level where method level annotations override those at the class level.

Can @transactional annotation only be used at class level?

Annotation Type Transactional. Describes a transaction attribute on an individual method or on a class. When this annotation is declared at the class level, it applies as a default to all methods of the declaring class and its subclasses.


2 Answers

The @Transactional is not related to synchronization. It just makes sure that your flow either succeeds or fails. Each hit has its own flow and its own success or failure.

I guess what you're experiencing is due to the use of shared data.

For example. If you have a class Foo that looks like this:

public class Foo {
    private static boolean flag = true;

    @Transactional
    public void doSomething() {
        flag = false;
    }
}

In this case it doesn't matter that you have many Foo instances because they all use the same flag.

Another scenario would be if you have one instance of Foo (very common if you use something like Spring) and you have data that is changed for this instance. You can look at the same Foo example and just remove the static from flag:

public class Foo {
    private boolean flag = true;

    @Transactional
    public void doSomething() {
        flag = false;
    }
}

In either of those cases you need to synchronize the data changes somehow. It has nothing to do with @Transactional.

like image 178
Avi Avatar answered Sep 22 '22 15:09

Avi


That transactions are database transactions and behavior is database engine dependant but it usually works this way:

  1. A thread enter the method.
  2. A thread enter the same or any other transactional method. It does not block as @Transactional is not about synchronization.
  3. One thread execute any query that blocks a database resource. Eg. SELECT * FROM MYTABLE FOR UPDATE;.
  4. Another thread try to execute anything that needs the same database resource. Eg. UPDATE MYTABLE SET A = A + 1; And it blocks.
  5. The thread that acquired the lock on step 3 completes the transactional method successfully making an implicit commit or fails making an implicit rollback.
  6. The blocked thread wakes up and continues as it can now get the resource that was locked.
like image 31
aalku Avatar answered Sep 25 '22 15:09

aalku