mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
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:
@@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user