hibernate - Can spring transactions unsynchronize a synchronized method? -


My colleagues and I have a web application that uses Spring 3.0.0 and J.A.A. (Hibernate 3.5.0-Beta 2 ) Is one of the data structures inside MyEclipse that is a tree. Just for fun, we tried to stress-testing the "Insert node" operation with Jmater, and found a concurrency problem. The Hibernate report searches for two entities with the same private key, such as after the warning:

  WARN [org.hibernate.engine.loading.LoadContexts] unsuccessful cleanup (archive) : ..  

It is quite easy to see if such issues can occur if multiple threads call the inserted () method together.

My servicelet calls a service layer object B .execute (), which then calls a lower level object (Cinsert). (The real code is too big to post, so it has been abbreviated to some extent.)

Servlet A:

  Public zero doPost (Request request, response Reaction) {.. B. Exempt (parameter); ...}  

Service B:

  @ Transactional ** ** Fix this problem to remove this line. Public synchronization is invalid (parameter) {log ("b.execute () is starting." = "+ This); ... c.insert (params); ... log ("b.execute () finishing. =" + This); }  

Sub-service C:

  Enter the public zero related to transaction (parameter) {... // data structure manipulation operation which / / b Simultaneous with some other helipulating operation called by ...}  

All my state-change passes through call B, so I decided to synchronize BXAQ () Taken . It was already @transial , but it is actually a business logic that needs to be synchronized, not just persistence, therefore seems appropriate

my cincert () The law was also the @Trainedaction but when spring transaction requires a default transaction, I do not think any new transaction is being made for concert ().

All components A, B and C spring- beans, and therefore if a single song is actually only a B object, then I think that at one time to execute b.execute () Should not be possible for more danger. When the load is light, only one thread is used, and this is the case. But under load, additional threads are included, and I think many threads "start" print before printing the first thread "finishing". It seems that the synchronize format of the method.

I decided to print this in the log message to ensure only one single object is displayed, all the log messages show the same object ID.

After more disappointing investigations, I found out that by removing @ Transactional for BXIQ () the problem is solved. With that line, I can have lots of threads, but I look "starting" after a "finishing" before the next "start" (and my data structures remain intact). Either way, synchronize works only when @transaction is not present. But I do not understand why anyone can help? How to see more tips about this?

In the mark of the stack, I can see that there is an app / seagull proxy generated between AEDO Post () and BXAQ () - and B.execute () and Cinert () I wonder if the proxy The creation of synchronize can ruin the behavior.

Synchronized keywords are required, as you have stated, the included object is always the same. I have not seen the above mentioned behavior myself, but your suspicion may just be right.

Have you tried to log out from doPost -method to b? If it is different every time, then there is some spring magic with AOP / seagull proxy.

However, I will not rely on synchronized keywords but Java Instead, the lock locks to ensure synchronization behavior, because your B object is always regardless of more than one potential cglib proxy.


Comments

Popular posts from this blog

sql - dynamically varied number of conditions in the 'where' statement using LINQ -

asp.net mvc - Dynamically Generated Ajax.BeginForm -

Debug on symbian -