mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.0 to HEAD
11535: Fix ETHREEOH-519, ETHREEOH-23, ETHREEOH-24, ETHREEOH-58, ETHREEOH-449, ETHREEOH-30, ETHREEOH-19, ETHREEOH-561, ETHREEOH-537, ETHREEOH-567, ETHREEOH-568, ETHREEOH-113, ETHREEOH-130, ETHREEOH-115, ETHREEOH-566, ETHREEOH-572, ETHREEOH-82. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12450 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.transaction;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.BatchUpdateException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Random;
|
||||
@@ -44,8 +45,11 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.hibernate.ObjectNotFoundException;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.StaleStateException;
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.dao.ConcurrencyFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DeadlockLoserDataAccessException;
|
||||
@@ -74,6 +78,7 @@ import org.springframework.jdbc.UncategorizedSQLException;
|
||||
public class RetryingTransactionHelper
|
||||
{
|
||||
private static final String MSG_READ_ONLY = "permissions.err_read_only";
|
||||
private static final String KEY_ACTIVE_TRANSACTION = "RetryingTransactionHelper.ActiveTxn";
|
||||
private static Log logger = LogFactory.getLog(RetryingTransactionHelper.class);
|
||||
|
||||
/**
|
||||
@@ -95,7 +100,8 @@ public class RetryingTransactionHelper
|
||||
DataIntegrityViolationException.class,
|
||||
StaleStateException.class,
|
||||
ObjectNotFoundException.class,
|
||||
RemoteCacheException.class
|
||||
CacheException.class, // Usually a cache replication issue
|
||||
RemoteCacheException.class // A cache replication issue
|
||||
};
|
||||
}
|
||||
|
||||
@@ -104,6 +110,8 @@ public class RetryingTransactionHelper
|
||||
*/
|
||||
private TransactionService txnService;
|
||||
|
||||
// /** Performs post-failure exception neatening */
|
||||
// private ExceptionTransformer exceptionTransformer;
|
||||
/** The maximum number of retries. -1 for infinity. */
|
||||
private int maxRetries;
|
||||
/** The minimum time to wait between retries. */
|
||||
@@ -151,6 +159,16 @@ public class RetryingTransactionHelper
|
||||
}
|
||||
|
||||
// Setters.
|
||||
|
||||
// /**
|
||||
// * Optionally set the component that will transform or neaten any exceptions that are
|
||||
// * propagated.
|
||||
// */
|
||||
// public void setExceptionTransformer(ExceptionTransformer exceptionTransformer)
|
||||
// {
|
||||
// this.exceptionTransformer = exceptionTransformer;
|
||||
// }
|
||||
//
|
||||
/**
|
||||
* Set the TransactionService.
|
||||
*/
|
||||
@@ -289,6 +307,14 @@ public class RetryingTransactionHelper
|
||||
if (txn != null)
|
||||
{
|
||||
txn.begin();
|
||||
// Wrap it to protect it
|
||||
UserTransactionProtectionAdvise advise = new UserTransactionProtectionAdvise();
|
||||
ProxyFactory proxyFactory = new ProxyFactory(txn);
|
||||
proxyFactory.addAdvice(advise);
|
||||
UserTransaction wrappedTxn = (UserTransaction) proxyFactory.getProxy();
|
||||
// Store the UserTransaction for static retrieval. There is no need to unbind it
|
||||
// because the transaction management will do that for us.
|
||||
AlfrescoTransactionSupport.bindResource(KEY_ACTIVE_TRANSACTION, wrappedTxn);
|
||||
}
|
||||
// Do the work.
|
||||
R result = cb.execute();
|
||||
@@ -340,12 +366,12 @@ public class RetryingTransactionHelper
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"Transaction commit failed: \n" +
|
||||
" Thread: " + Thread.currentThread().getName() + "\n" +
|
||||
" Txn: " + txn + "\n" +
|
||||
" Iteration: " + count + "\n" +
|
||||
" Exception follows:",
|
||||
e);
|
||||
"Transaction commit failed: \n" +
|
||||
" Thread: " + Thread.currentThread().getName() + "\n" +
|
||||
" Txn: " + txn + "\n" +
|
||||
" Iteration: " + count + "\n" +
|
||||
" Exception follows:",
|
||||
e);
|
||||
}
|
||||
// Rollback if we can.
|
||||
if (txn != null)
|
||||
@@ -440,4 +466,44 @@ public class RetryingTransactionHelper
|
||||
return retryCause;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to get the active transaction. The transaction status can be queried and
|
||||
* marked for rollback.
|
||||
* <p>
|
||||
* <b>NOTE:</b> Any attempt to actually commit or rollback the transaction will cause failures.
|
||||
*
|
||||
* @return Returns the currently active user transaction or <tt>null</tt> if
|
||||
* there isn't one.
|
||||
*/
|
||||
public static UserTransaction getActiveUserTransaction()
|
||||
{
|
||||
// Dodge if there is no wrapping transaction
|
||||
if (AlfrescoTransactionSupport.getTransactionReadState() == TxnReadState.TXN_NONE)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Get the current transaction. There might not be one if the transaction was not started using
|
||||
// this class i.e. it wasn't started with retries.
|
||||
UserTransaction txn = (UserTransaction) AlfrescoTransactionSupport.getResource(KEY_ACTIVE_TRANSACTION);
|
||||
if (txn == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Done
|
||||
return txn;
|
||||
}
|
||||
|
||||
private static class UserTransactionProtectionAdvise implements MethodBeforeAdvice
|
||||
{
|
||||
public void before(Method method, Object[] args, Object target) throws Throwable
|
||||
{
|
||||
String methodName = method.getName();
|
||||
if (methodName.equals("begin") || methodName.equals("commit") || methodName.equals("rollback"))
|
||||
{
|
||||
throw new IllegalAccessException(
|
||||
"The user transaction cannot be manipulated from within the transactional work load");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user