ALF-3773 - RetryingTransactionHelperTest hangs for PostgreSQL build

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21494 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2010-07-29 16:06:35 +00:00
parent c1018c5675
commit a272009f7e

View File

@@ -28,6 +28,7 @@ import junit.framework.TestCase;
import org.alfresco.error.ExceptionStackUtil; import org.alfresco.error.ExceptionStackUtil;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState; import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
@@ -41,7 +42,8 @@ import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.apache.commons.lang.mutable.MutableInt; import org.apache.commons.lang.mutable.MutableInt;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.engine.TransactionHelper; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@@ -67,12 +69,16 @@ public class RetryingTransactionHelperTest extends TestCase
private NodeService nodeService; private NodeService nodeService;
private RetryingTransactionHelper txnHelper; private RetryingTransactionHelper txnHelper;
private Dialect dialect;
private NodeRef rootNodeRef; private NodeRef rootNodeRef;
private NodeRef workingNodeRef; private NodeRef workingNodeRef;
@Override @Override
public void setUp() throws Exception public void setUp() throws Exception
{ {
dialect = (Dialect) ctx.getBean("dialect");
serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
transactionService = serviceRegistry.getTransactionService(); transactionService = serviceRegistry.getTransactionService();
@@ -367,12 +373,21 @@ public class RetryingTransactionHelperTest extends TestCase
/** /**
* Checks nesting of two transactions with <code>requiresNew == true</code>, * Checks nesting of two transactions with <code>requiresNew == true</code>,
* but where the two transactions get involved in a concurrency struggle. * but where the two transactions get involved in a concurrency struggle.
*
* Note: skip test for PostgreSQL
*/ */
@SuppressWarnings("unchecked") public void testNestedWithoutPropogationConcurrentUntilFailureNotPostgreSQL() throws InterruptedException
public void testNestedWithoutPropogationConcurrentUntilFailure()
{ {
final RetryingTransactionHelper txnHelperForTest = transactionService.getRetryingTransactionHelper(); final RetryingTransactionHelper txnHelperForTest = transactionService.getRetryingTransactionHelper();
txnHelperForTest.setMaxRetries(1); txnHelperForTest.setMaxRetries(1);
if (dialect instanceof PostgreSQLDialect)
{
// NOOP - skip test for PostgreSQL since it does not support lock wait timeout hence will hang if concurrently "nested" (in terms of Spring) since the initial transaction does not complete
// see testConcurrencyRetryingNoFailure instead
}
else
{
RetryingTransactionCallback<Long> callback = new RetryingTransactionCallback<Long>() RetryingTransactionCallback<Long> callback = new RetryingTransactionCallback<Long>()
{ {
public Long execute() throws Throwable public Long execute() throws Throwable
@@ -401,6 +416,63 @@ public class RetryingTransactionHelperTest extends TestCase
assertNotNull("Unexpected cause of the failure", validCause); assertNotNull("Unexpected cause of the failure", validCause);
} }
} }
}
public void testConcurrencyRetryingNoFailure() throws InterruptedException
{
Thread t1 = new Thread(new ConcurrentTransaction(5000));
t1.start();
Thread.sleep(1000);
Thread t2 = new Thread(new ConcurrentTransaction(10));
t2.start();
t1.join();
t2.join();
}
private class ConcurrentTransaction implements Runnable
{
private long wait;
public ConcurrentTransaction(long wait)
{
this.wait = wait;
}
public void run()
{
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
final RetryingTransactionHelper txnHelperForTest = transactionService.getRetryingTransactionHelper();
RetryingTransactionCallback<Long> callback = new RetryingTransactionCallback<Long>()
{
public Long execute() throws Throwable
{
incrementCheckValue();
System.out.println("Wait started: "+Thread.currentThread()+" ("+wait+")");
Thread.sleep(wait);
System.out.println("Wait finished: "+Thread.currentThread()+" ("+wait+")");
return getCheckValue();
}
};
try
{
System.out.println("Txn start: "+Thread.currentThread()+" ("+wait+")");
txnHelperForTest.doInTransaction(callback);
System.out.println("Txn finish: "+Thread.currentThread()+" ("+wait+")");
}
catch (Throwable e)
{
Throwable validCause = ExceptionStackUtil.getCause(e, RetryingTransactionHelper.RETRY_EXCEPTIONS);
assertNotNull("Unexpected cause of the failure", validCause);
}
}
}
public void testLostConnectionRecovery() public void testLostConnectionRecovery()
{ {