0

I wanted to ask, if the annotation @Transactional of JPA can cause an race condition.

Following scenario:

  • Program A is a java application which has an method with @Transactional annotation -> this method updates a column of a line X in the database
  • Program B writes after the update of Program A a change into line X
  • Program A's transactional method throws an exception and starts the rollback

What happens while these rollback? Is line X in the state which it has before program A started its method? Or does the @Transactional method log the table while access so no concurrent write access can happen? I think the update must happen while the transactional method, because I read the count of updated rows while that method and I throw an exception if that count isn't exact 1. I think this triggers the UPDATE operation. So some real rollback must happen (?) I read some information about @Transactional but I have not enough information about the whole JPA context to understand it ...

Maybe somebody could help me with my question.

Thanks ;)

Tim
  • 71
  • 1
  • 9
  • Isn't this answers your question? https://stackoverflow.com/questions/38361098/race-condition-between-transactions – Maneesha Indrachapa Aug 31 '21 at 15:38
  • This doesn’t seem to make sense. B can’t write “after” A because A hasn’t committed anything yet. Assuming write by A in step 1 is in the transaction that rolls back in step 3. Or did you mean something else? – Nathan Hughes Aug 31 '21 at 15:48
  • You might want to read up on database transactions as well as transaction isolation. As Nathan already pointed out, since A's transaction gets rolled back, it won't write anything to the DB. Note that JDBC (which JPA is using) executes every statement in a transaction, `@Transactional` just manages the lifetime of those transactions, i.e. if you have 2 statements in such a method they will be executed in the same DB transaction which will be committed or rolled back at the end of the method. Without a Spring transaction every statement would use its own DB transaction. – Thomas Aug 31 '21 at 16:04
  • But I have ```java int updatedCount = myRepo.setState(...); if(updatedCount != 1) { throw new IllegalArgumentException(); } ``` So it rolls back if the update didn't hit one row in the table. I don't understand how this update in the table could not be executed before the end of the transactional method? – Tim Sep 01 '21 at 07:56
  • @Tim it effectively executes what would happen if the transaction were committed. The changes are only _really_ committed to the database once your method returns. You could conceptually consider it somewhat like a dry-run, that is converted into an actual run if (and only if) it succeeds. (Not 100% accurate, but a useful analogy) – tjalling Nov 10 '22 at 19:50

0 Answers0