Hi group, we use Hibernate 3.6.1 together with MySQL 5.0/5.1 (InnoDB dialect) in our project. Currently, we are facing the problem of getting a lock on an object that has not been persisted yet:
public class OurObject { Long id; String name; Set<Element> myelements; }
We have an API method "void addElementToObject(String name, Element someElem)" with a straight-forward algorithm: Begin Transaction. Look up the object with the given natural id in the DB (HQL query). If it's there, that will be great. Otherwise, create the object first. Then add the element. Committ and end transaction. If you run into any exception, make a rollback.
We ran into the problem that two independent processes couldn't find the object with the given name and created it, so that we ended up with two objects with that name. We could fix that issue by turning "name" into a natural-id and catching the ConstraintViolationException thrown by JDBC. However, we are not entirely satisfied with that solution. Is there any stable, probate, and Hibernate-conformant way of creating a write lock on a table every time "addElementToObject" is called?
One strategy we persued was to play with the "Lock table as ..." and "unlock tables" statement offered by MySQL. But this was unstable and resulted in deadlocks. Also, we didn't manage to persuade Hibernate to put the "unlock tables" statement at the very end of the transaction.
Another strategy was to create the object first with a committ, and then make an UPGRADE lock: session.buildLockRequest(LockLevel.UPGRADE).lock() But that also has resulted in instabilities. Further, if anything goes wrong with adding the element, the rollback can't affect the newly created object. Thanks in advance for your help!
|