-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page Previous  1, 2
Author Message
 Post subject:
PostPosted: Mon Nov 03, 2003 6:24 am 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
Gavin,

From the SQL-92 spec: "When a <commit statement> is executed, all constraints are effectively checked and, if any constraint is not satisfied, then an exception condition is raised and the transaction is terminated by an implicit <rollback statement>."

So even if classic JDBC examples have the commit statements in the try block, it is unnecessary to explicitly call rollback on commit failure. Therefore, I even more strongly support the "rollback-on-HibernateException-but-not-on-TransactionException" idiom, as it also matches JTA's model. Also supporting the "rollback-on-any-exception-including-commit-failure" idiom shouldn't be hard to do, but I definitely consider the "commit-OR-rollback" model cleaner.

So what about the following implementation of JDBCTransaction:

Code:
public void commit() throws HibernateException {
  if (!begun) throw new TransactionException("Transaction not successfully started");
  log.debug("commit");
  if ( session.getFlushMode()!=FlushMode.NEVER ) session.flush();
  try {
    session.connection().commit();
    committed = true;
    session.afterTransactionCompletion(true);
  }
  catch (SQLException e) {
    log.error("Commit failed", e);
    session.afterTransactionCompletion(false);
    throw new TransactionException("Commit failed with SQL exception: ", e);
  }
  finally {
    toggleAutoCommit();
  }
}
   
public void rollback() throws HibernateException {
  if (!begun) throw new TransactionException("Transaction not successfully started");
  log.debug("rollback");
  try {
    session.connection().rollback();
    rolledBack=true;
  }
  catch (SQLException e) {
    log.error("Rollback failed", e);
    throw new TransactionException("Rollback failed with SQL exception: ", e);
  }
  finally {
    session.afterTransactionCompletion(false);
    toggleAutoCommit();
  }
}


That implementation would leave both the connection and the session in a valid state after an actual commit attempt, in any case -- concerning autoCommit state and afterTransactionCompletion call. If flushing failed, a non-TransactionException HibernateException will get thrown, and no autoCommit change or afterTransactionCompletion call will have happened -- as application code is assumed to explicitly call rollback in that case.

If application code explicitly calls rollback on TransactionException too, an unnecessary rollback of an empty JDBC transaction will occur, and another reset of autoCommit state plus another afterTransactionCompletion call (none of these should matter). So effectively, the above implementation would support both idioms: Application developers are able to choose between "explicit-rollback-on-commit-failure" vs "commit-or-rollback" then. What do you think?

Juergen


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 03, 2003 6:59 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
ok then, so what I've done is added a flag to JDBCTransaction so that if Connection.commit() fails, we don't call Connection.rollback(). Easy. Now neither strategy will call rollback after a failed commit.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 03, 2003 8:33 am 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
gavin wrote:
ok then, so what I've done is added a flag to JDBCTransaction so that if Connection.commit() fails, we don't call Connection.rollback(). Easy. Now neither strategy will call rollback after a failed commit.


So, do you agree regarding support for both strategies? As I've indicated, you would need to make sure that Transaction.commit() properly completes the Hibernate transaction even in case of a Connection.commit() failure, to support the "commit-or-rollback" idiom too.

Actually, this would be very similar to JDO's transaction model then: Application code needs to explicitly roll back on flushing failure (non-JDOFatalException ^= non-TransactionException) but not on on commit failure (JDOFatalException ^= TransactionException).

Sorry for being so perseverant, but I'd really like to get this straight!

Juergen


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page Previous  1, 2

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.