Hi.
I post this thread to talk about transactional behavior.
I'm using Spring 2.5.
I have (as almost every body) the transactional behavior in the business objects layer. Also, I'm using the Spring 2.0 tx namespace to do it.
Of course, it works well.
I have a method in one business object that returns a long data.
To simplify, let's think that the method is
public long getNumber(){....}
It's important to note that this method calls a DAO to update a field of the number (the number has a table in the database) to change its status (the number passes from an available status to a reserved status). The idea is that changing the status, the number is reserved for a client, and it's not possible to give that number to another client.
In production, I had a lot of concurrency (there is a web service that requests this business method several times a second). Then, I got the same result (the same number) with some of the requests and this was not the result expected.
So, my first fix was to introduce the synchronized, so the method was finally
public synchronized long getNumber(){....}
I thought this was a good idea, because the business object was in the Spring container (with only one instance in the container of this object).
Then, all was good in a high percentage, but suddenly, a very few of the calls to the method returned the same number again. Most of the concurrent calls worked well, but few worked bad.
I'd like to know the reason of this. By the way, the isolation level of the transaction is DEFAULT(<tx:method name="*" isolation="DEFAULT" />).
Maybe, is it about the AOP behaviour? I.e., the synchronized is only for the target class and not for the proxied class that manages the transactional behavior for the target class.
What's your opinion about this? (Bad operation with synchronized in few requests)
Thank you very much in advance.
P.D.: FInally, I fixed the problem introducing locks in a database level. I'm using Oracle, so I used "SELECT .... FOR UPDATE" before updating the status of the number. In any case, I'd like to know the possible reason of the results I get. Another possibility could be set the isolation level to serializable, for example, but I didn't want to lower the performance too much. Maybe, this isolation level could lock all the table. With "SELECT.. FOR UPDATE" I can only lock the rows I want.


Reply With Quote