I have several use cases where a particular unit of work needs to process several tasks, each wrapped in it's own transaction. One of those tasks may fail, but I need to continue operation on the remaining tasks. An example of a use case involved is that I want to do a task to a collection of orders. If that task fails for ONE order, I still want to continue processing the remaining orders.
Up till now, I would simply call transaction.rollback(), and continue on my merry way, creating a new transaction for the next task. However, I recently discovered that even though a transaction may be rolled back, the objects involved in that transaction still live in the session cache, and consequent operations may trigger a session flush and write changes in those objects back to the db... bad.
So I tried to get clever, and decided that each time i roll back a transaction, i would clear() the session. This prevents flushing of the "bad" objects, but also disconnects objects i want to continue to use, but which are now evicted.
My question is this: what is a good design practice in this case?
- does each transaction warrant a brand new session?
- can I get around the original issue (objects involved in a rolled-back transaction being flushed) by changing the flush mode? If flush mode is not auto, is the DML "queue" cleared after a rollback(), so that if a new transaction is started and committed, only those changes are persisted?
- or am I doing down the wrong though process here altogether?
I am using a one-session-per-request design, where I open a session at the beginning of an HTTP request, and close it at the end. I load objects that are needed for the entire unit of work (such as current user, etc.) at the beginning - and this is why I want to avoid closing and opening a new session for each transaction within that one request.
Thanks very much for any insight.
Hibernate version:
1.2.1 GA
-Sasha Borodin
|