Merge pull request #15 from Alfresco/fix/repo-3589_TransactionListeners_unpredictable

Fix/repo 3589 transaction listeners unpredictable
This commit is contained in:
Martin Muller
2018-07-11 13:04:50 +01:00
committed by GitHub
2 changed files with 83 additions and 3 deletions

View File

@@ -480,7 +480,7 @@ public abstract class TransactionSupportUtil
// These are still considered part of the transaction so are executed here
doBeforeCommit(readOnly);
// Now run the > 0 listeners beforeCommit
// Now run the != 0 listeners beforeCommit
Set<Integer> priorities = priorityLookup.keySet();
SortedSet<Integer> sortedPriorities = new ConcurrentSkipListSet<Integer>(FORWARD_INTEGER_ORDER);
@@ -526,8 +526,7 @@ public abstract class TransactionSupportUtil
*/
private void doBeforeCommit(Set<TransactionListener> visitedListeners, boolean readOnly)
{
Set<TransactionListener> listeners = priorityLookup.get(0);
Set<TransactionListener> pendingListeners = new HashSet<TransactionListener>(listeners);
List<TransactionListener> pendingListeners = getLevelZeroListenersIterable();
pendingListeners.removeAll(visitedListeners);
if (pendingListeners.size() != 0)

View File

@@ -19,6 +19,7 @@
package org.alfresco.util.transaction;
import java.util.NoSuchElementException;
import java.util.Objects;
import javax.transaction.RollbackException;
import javax.transaction.Status;
@@ -321,6 +322,86 @@ public class SpringAwareUserTransactionTest extends TestCase
TransactionDefinition.TIMEOUT_DEFAULT);
}
public void testTransactionListenerOrder() throws Throwable
{
testNoTxnStatus();
try
{
txn.begin();
StringBuffer buffer = new StringBuffer();
TransactionSupportUtil.bindListener(new TestTransactionListener("5x", buffer), 5);
TransactionSupportUtil.bindListener(new TestTransactionListener("0a", buffer), 0);
TransactionSupportUtil.bindListener(new TestTransactionListener("0e", buffer), 0);
TransactionSupportUtil.bindListener(new TestTransactionListener("0d", buffer), 0);
TransactionSupportUtil.bindListener(new TestTransactionListener("0b", buffer), 0);
TransactionSupportUtil.bindListener(new TestTransactionListener("0c", buffer), 0);
TransactionSupportUtil.bindListener(new TestTransactionListener("4x", buffer), 4);
TransactionSupportUtil.bindListener(new TestTransactionListener("1x", buffer), -1);
TransactionSupportUtil.bindListener(new TestTransactionListener("3a", buffer), 3);
TransactionSupportUtil.bindListener(new TestTransactionListener("3e", buffer), 3);
TransactionSupportUtil.bindListener(new TestTransactionListener("3d", buffer), 3);
TransactionSupportUtil.bindListener(new TestTransactionListener("3b", buffer), 3);
TransactionSupportUtil.bindListener(new TestTransactionListener("3c", buffer), 3);
TransactionSupportUtil.bindListener(new TestTransactionListener("2x", buffer), -2);
txn.commit();
assertEquals("0a0e0d0b0c2x1x3a3e3d3b3c4x5x", buffer.toString());
}
catch (Exception e)
{
try
{
txn.rollback();
}
catch (Exception ee)
{
e.addSuppressed(ee);
}
throw e;
}
checkNoStatusOnThread();
}
private static class TestTransactionListener extends TransactionListenerAdapter
{
private final String name;
private final StringBuffer buffer;
public TestTransactionListener(String name, StringBuffer buffer)
{
Objects.requireNonNull(name);
Objects.requireNonNull(buffer);
this.name = name;
this.buffer = buffer;
}
@Override
public void beforeCommit(boolean readOnly)
{
buffer.append(name);
}
public String getName()
{
return name;
}
@Override
public boolean equals(Object obj)
{
if (obj instanceof TestTransactionListener)
{
return name.equals(((TestTransactionListener) obj).getName());
}
return false;
}
@Override
public int hashCode()
{
return name.hashCode();
}
}
/**
* Used to check that the transaction manager is being called correctly
*