This checks in the current state of WCM development.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3128 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-06-16 16:59:15 +00:00
parent 6b52660c8a
commit 936f6d7021
57 changed files with 9563 additions and 3827 deletions

View File

@@ -17,10 +17,16 @@ package org.alfresco.repo.avm.hibernate;
* License.
*/
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.alfresco.repo.avm.AVMException;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StaleStateException;
import org.hibernate.Transaction;
import org.hibernate.exception.GenericJDBCException;
/**
* Helper for DAOs.
@@ -33,6 +39,16 @@ public class HibernateTxn
*/
private SessionFactory fSessionFactory;
/**
* The random number generator for inter-retry sleep.
*/
private Random fRandom;
/**
* The BFL.
*/
private ReentrantReadWriteLock fLock;
/**
* Make one up.
* @param sessionFactory The SessionFactory.
@@ -40,52 +56,110 @@ public class HibernateTxn
public HibernateTxn(SessionFactory sessionFactory)
{
fSessionFactory = sessionFactory;
fRandom = new Random();
fLock = new ReentrantReadWriteLock(true); // Make the lock fair.
}
/**
* Perform a set of operations under a single Hibernate transaction.
* Keep trying if the operation fails because of a concurrency issue.
* @param callback The worker.
* @param write Whether this is a write operation.
* @return Whether the operation finished with a commit.
*/
public boolean perform(HibernateTxnCallback callback)
public void perform(HibernateTxnCallback callback, boolean write)
{
Session sess = null;
Transaction txn = null;
try
while (true)
{
sess = fSessionFactory.openSession();
txn = sess.beginTransaction();
callback.perform(sess);
txn.commit();
return true;
}
catch (Throwable t)
{
t.printStackTrace(System.err);
if (txn != null)
try
{
try
/*
if (write)
{
txn.rollback();
fLock.writeLock().lock();
}
catch (HibernateException he)
else
{
// Do nothing.
fLock.readLock().lock();
}
*/
sess = fSessionFactory.openSession();
txn = sess.beginTransaction();
callback.perform(sess);
txn.commit();
return;
}
return false;
}
finally
{
if (sess != null)
catch (Throwable t)
{
try
// TODO Add appropriate logging.
if (txn != null)
{
sess.close();
try
{
txn.rollback();
}
catch (HibernateException he)
{
// Do nothing.
}
// If we've lost a race or we've deadlocked, retry.
if (t instanceof StaleStateException ||
t instanceof GenericJDBCException)
{
if (t instanceof StaleStateException)
{
System.err.println("Lost Race");
continue;
}
System.err.println("Deadlock");
try
{
long interval;
synchronized (fRandom)
{
interval = fRandom.nextInt(1000);
}
Thread.sleep(interval);
}
catch (InterruptedException ie)
{
// Do nothing.
}
continue;
}
}
catch (HibernateException he)
if (t instanceof AVMException)
{
// Do nothing.
throw (AVMException)t;
}
// TODO Crack t into more useful exception types.
// Otherwise nothing we can do except throw.
throw new AVMException("Unrecoverable error", t);
}
finally
{
/*
if (write)
{
fLock.writeLock().unlock();
}
else
{
fLock.readLock().unlock();
}
*/
if (sess != null)
{
try
{
sess.close();
}
catch (HibernateException he)
{
// Do nothing.
}
}
}
}