-->
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.  [ 1 post ] 
Author Message
 Post subject: Serialization Isolation database fails with 3.0 example
PostPosted: Sat Jul 09, 2005 10:16 pm 
Newbie

Joined: Wed Sep 01, 2004 1:32 pm
Posts: 9
Location: (eastern) North Carolina
I have implemented a Hibernate solution that I belive should greatly reduce the chances of a concurrent serializable transaction conflict from occurring when using databases with serializable isolation. I would appreciate a review of this solution, by the users of this forum, to make sure I haven't missed something.

A user on the Mckoi forum was having trouble with running the Hibernate 3.0 example, i.e. '>build.bat eg', against Mckoi database. Mckoi has 'transaction serializable' isolation. 'Read commited' isolation is not available.

The exception was:
Code:

[java] 08:20:44,741 ERROR JDBCTransaction:104 - JDBC commit failed
[java] com.mckoi.database.jdbc.MSQLException: Concurrent
Serializable Transaction Conflict (2): Table altered/dropped: AuctionUser


I suspect that there was more than one connection involved, and the Connection that raised the exception was working from a stale 'image' of the database. So, as a temperary solution I had the user set autocommit to true in /etc/hibernate.properties.

Code:
hibernate.connection.autocommit true


This 'fixed' the problem. Of course this isn't much of a solution if multiple DML statements are occurring within what is supposed to be a single Hibernate transaction.

I had an idea of what I wanted, I implemented it, and it appears to work. The idea was to always 'begin' a Hibernate transaction, i.e. session.beginTransaction() with either a commit() or rollback() to the database to ensure that the connection had the freshest possible 'image' of the database before the session did any work.

I checked the code in Hibernate 3.0 and did not find any commit() or rollback() occurring at beginning of transaction.

So, I extended JDBCTransaction, which does the desired rollback() on the overridden begin() method. There is a Factory class also, which needs to be used to get the new Transaction class. The code for properties file and two classes follows.

Change transaction factory in hibernate.properties.
Code:
hibernate.transaction.factory_class
org.hibernate.transaction.SerializableIsolationTransactionFactory


transaction class SerializableIsolationTransaction
Code:
package org.hibernate.transaction;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.transaction.Status;
import javax.transaction.Synchronization;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.hibernate.HibernateException;
import org.hibernate.Transaction;
import org.hibernate.TransactionException;
import org.hibernate.jdbc.JDBCContext;

public class SerializableIsolationTransaction extends JDBCTransaction {
 
  private static final Log log = LogFactory.getLog(SerializableIsolationTransaction.class);
   private final JDBCContext jdbcContext;

   public SerializableIsolationTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
      super( jdbcContext, transactionContext );
      this.jdbcContext = jdbcContext;
   }

   public void begin() throws HibernateException {
      try {
          jdbcContext.connection().rollback();
      } catch (SQLException e) {
         log.error("begin() rollback failed", e);
         throw new TransactionException("begin() rollback failed: ", e);
      }
    super.begin();
   }
}


the factory
Code:
package org.hibernate.transaction;

import java.util.Properties;

import org.hibernate.ConnectionReleaseMode;
import org.hibernate.Transaction;
import org.hibernate.HibernateException;
import org.hibernate.jdbc.JDBCContext;

public final class SerializableIsolationTransactionFactory implements TransactionFactory {

   public ConnectionReleaseMode getDefaultReleaseMode() {
      return ConnectionReleaseMode.AFTER_TRANSACTION;
   }

   public Transaction beginTransaction(JDBCContext jdbcContext, Context transactionContext) throws HibernateException {
      JDBCTransaction tx = new SerializableIsolationTransaction( jdbcContext, transactionContext );
      tx.begin();
      return tx;
   }

   public void configure(Properties props) throws HibernateException {}
}


Please advise.

Thanks & Regards, Jim


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

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.