Reputation: 557
I read about the propagation and isolation in the spring/hibernate. I have one specific method where we have
0. @Transactional (the default spring annotation)
1. read several rows
2. some business logic
3. read (from other table using some data from the first read)
That looks a bit unsafe to me. What if someone else deletes a row during step 2. I think that I should change the method annotation to
@Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE)
Is that a valid fix for my specific case? (the task is to fix transactional annotations causing some problems with the system and change as few other lines of code as possible) Thanks in advance.
Upvotes: 0
Views: 1858
Reputation: 479
It depend what you mean by unsafe, what you business logic you write, in your example you only performing a read operations while the serializable is recommended in quick read/write operations, also in your case if something being updated in first table a serializable transaction will operates as nothing being executed- like a frozen environment , As long as others transactions insert data it will be invisible for you, hence at end the result of your second read could be wrong
As they mention on oracle as example :
Database inconsistencies can result unless such application-level consistency checks are coded with this in mind, even when using serializable transactions.
Also when you used serializable here you must be aware of cannot serialize access exception that can occur inside your code (other class) while you try to update the same table, which could be tricky
Another approach to solve that is use Read Committed Isolation and while you re-implementing the second read keep in mind representing the real state of database, i mean if other rows receive update and commit they must be taking into consideration using data used in first read, without a real example of your method i can't give you full working example.
Upvotes: 1
Reputation: 1723
If i understood your case, you have some method, which do several reading from database.
So, if your method just read from DB, so you just need to have annotation like: @Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE)
Because in fact you just read from database.
But if your method provide both access to database read & write - the best way is to separate it to two methods, and one of them would be readOnly.
Upvotes: 1