Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

"Pro Hibernate 3", Chapter9, GenerateDeadlock

 
Robert Fischer
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Has anyone successfully run this example using Hibernate 3.1.2 and MySQL 5? I got into a big stink with the Hibernate folks over this example: http://blog.hibernate.org/cgi-bin/blosxom.cgi/Steve%20Ebersole/deadlocks.html

The issue essentially is this: GenerateDeadlock does not behave as the authors would lead you to believe. There are 2 missing ingredients, 1. serializable transaction isolation level (which can be set globally in hibernate.properties or in the code), and 2. calling flush() after step1() and step2(). Even after adding these the code is still not catching a HibernateException on deadlock, instead a "lock wait timeout" exception is thrown. This implies that the DB is not throwing a deadlock exception, something which should not be because I'm using INNODB which supposedly is ACID compliant. The Hibernate folks are refusing to be helpful because they describe this as "bogus", "silly", "nonsense". If it's so trivial to get this example working correctly you'd think they wouldn't be put out over helping. Perhaps it's really not so trivial. At any rate if anyone has successfully run GenerateDeadlock with the above 2 additions against MySQL 5 I'd like to hear from you. Those interested in trying the code examples from "Pro Hibernate 3" can go to www.apress.com and download the zip file.
 
Robert Fischer
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Got it to work. Here's my comments to one of the authors:

To summarize the things needed to fix the original example:
1. Isolation level. I used level 8 which may be extreme, but I'm accustomed to working on applications requiring time ordered transaction completion (such as financial).
2. session.flush() after each work unit of each transaction. Synchronization errors will result otherwise.
3. fork=true in build script. This is a huge find that didn't occur to me at all. I actually thought log4j is broken (it still might be, but this wasn't evidence to support that conclusion).

There does seem to be some sort of log4j bug present. Often the following error is generated:
/root/proHibernate3/Chapter09> ant deadlock
Buildfile: build.xml

deadlock:
[java] Task A begins a transaction.
[java] Task A step 1
[java] Pausing Task A
[java] Task A is complete (paused)
[java] Task B begins a transaction.
[java] Task B step 1
[java] Pausing Task B
[java] Exception in thread "main" java.lang.NullPointerException
[java] at com.hibernatebook.chapter09.deadlock.GenerateDeadlock.main(Unknown Source)

If a System.out.println() is inserted anywhere in main() before starting the 2 threads then this problem goes away!

I would also recommend rewriting createUser(), step1(), and step2() to simply replace the contents of the username field regardless of what it presently contains. This makes it convenient to run back-to-back iterations of 'ant deadlock'.

With the above fixes the GenerateDeadlock example runs flawlessly, with deadlock being detected and a subsequent Hibernate exception being generated on every run. This is the crucial issue that the Hibernate folks either didn't understand or were unwilling to help with, namely that correct status is communicated to the application regardless of what steps the DB might take on the client's behalf.

Thanks for your help. This was a very illuminating exercise with regards to Hibernate, JDBC, MySQL 5, and log4j.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic