Inlining again. Sorry.
----- Original Message -----
From: "Allen Gilliland" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Monday, April 10, 2006 9:28 AM
Subject: Re: Roller persistence transactions, do we need begin(), commit(),
rollback()?
Anil, thanks for taking a look. I have some comments inline ...
Anil Gangolli wrote:
Hi Allen:
I took a quick, not very thorough look. A couple of comments/questions:
(1) In the manager implementations, there are some method bodies now that
have the following pattern:
try {
this.strategy.getSession().beginTransaction();
... do some work
this.strategy.getSession().getTransaction().commit();
} catch (HibernateException ex) {
try {
this.strategy.getSession().getTransaction().rollback();
} catch (HibernateException ex) {
log.error("Error during rollback", he);
}
strategy.release();
throw new RollerException(ex);
}
The first catch probably needs to be much more general, catching either
Exception or Throwable. Perhaps the second too, or put the release in
a finally at that scope. This form of exception handling recurs often
enough to make it an additional method (on the Hibernate strategy?)
I can change it to catch a greater scope of exceptions, but I believe
Hibernate wraps all of its exceptions in some version of the
HibernateException, so I imagine this should be fine.
The concern is that other calls made, not just Hibernate work, in the "...do
some work" sections can throw different runtime exceptions and errors
between the two points.
(2) Some methods commit, but some do not; they use
beginTransaction() (which does have the appropriate conditional
semantics) but do not commit. This seems to be intentional and intended
to facilitate composition of calls within one transaction for those
methods. However, I coudn't see an easy way to tell which methods are of
which type without looking at the method bodies. This could be handled in
the JavaDoc comments or perhaps better by some naming conventions.
All XXXManager methods are committed before ending. Some methods in the
HibernatePersistenceStrategy class do not commit for the reason you
mentioned, so that they can be used multiple times before committing.
There are some methods of the HibernatePersistenceStrategy which do
commit, but I think they are clearly marked as xxxAndCommit().
So I'm not really sure where the confusion is coming from. In general,
the assumption moving forward is that any call to XXXManager.method()
results in a commit, assuming it is a write operation.
OK. I must have missed this pattern.
(3) Concern/question: With this scoping of commit() we might see
increased likelihood of weird behavior in views immediately after commits
on some databases. In particular (a) in some databases they might not
yet reflect committed changes of the transaction just committed in other
transactions and (b) we might hit LazyInitializationExceptions . For
some background on the latter issue see the Hibernate reference manual
Section 11.1 and 11.1.1, and http://www.hibernate.org/43.html,
particularly the FAQ 'Can I commit the transaction before rendering the
view?' The latter problem could be addressed by ensuring we create a
second transaction for the view before any objects in the session get
referenced by the view code; maybe this is what you are already doing,
but it wasn't clear this is happening. Is it already dealt with?
This sounds more like a Hibernate issue than an architecture issue to me.
The fact is that this issue will exist in any implementation because
thread1 could have just committed some changes a split second after
thread2 read those same objects for use. Obviously we don't want to be
getting LazyInitializationExceptions, but again, that is a Hibernate
issue, not an architecture issue.
Hibernate demands that all operations happen within a transaction, so if
you peek at the code you will see that all XXXManager methods begin with a
call to session.beginTransaction().
No it's not a Hibernate issue. However, if all of our operations forward to
views which go back to the manager methods as you indicate to repopulate a
session, then we're probably fine.
(4) Impertinent comment: The approach of moving the demarcation up to a
Filter (rather than down to the manager code) still seems cleaner and
more conventional to me.
I am still not sure I believe this, but I am happy to do it if we really
need to.
-- Allen
--a.
----- Original Message ----- From: "Allen Gilliland"
<[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Saturday, April 08, 2006 6:26 PM
Subject: Re: Roller persistence transactions, do we need begin(),
commit(), rollback()?
Ok, first set of changes have been committed for anyone who wants to
take a look.
Most of the re-architecting has been done now and I have begun cleaning
up the things that got broken in the process. So far I have cleaned up
pretty much all of the basic stuff, including operations on users,
roles, websites, permissions, and website templates.
The next things I'll be cleaning up will be pings, weblog contents
(entries, categories, bookmarks, comments, referers), and then the
planet manager.
-- Allen