diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java index 487d66225..18ab5668b 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java @@ -478,7 +478,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests { ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager() { private boolean failed = false; protected void doCommit(DefaultTransactionStatus status) throws TransactionException { - if (writer.getWritten().isEmpty() || failed || !status.isNewTransaction()) { + if (writer.getWritten().isEmpty() || failed || !isExistingTransaction(status.getTransaction())) { super.doCommit(status); return; } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/ResourcelessTransactionManager.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/ResourcelessTransactionManager.java index ffce507ae..f130eebbb 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/ResourcelessTransactionManager.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/ResourcelessTransactionManager.java @@ -58,11 +58,11 @@ public class ResourcelessTransactionManager extends AbstractPlatformTransactionM if (TransactionSynchronizationManager.hasResource(this)) { @SuppressWarnings("unchecked") Stack stack = (Stack) TransactionSynchronizationManager.getResource(this); - return stack.size()>1; + return stack.size() > 1; } return ((ResourcelessTransaction) transaction).isActive(); } - + protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException { } @@ -70,12 +70,8 @@ public class ResourcelessTransactionManager extends AbstractPlatformTransactionM @SuppressWarnings("unchecked") Stack list = (Stack) TransactionSynchronizationManager.getResource(this); Stack resources = list; - if (!resources.isEmpty()) { - resources.pop(); - } - if (resources.isEmpty()) { - TransactionSynchronizationManager.unbindResource(this); - } + resources.clear(); + TransactionSynchronizationManager.unbindResource(this); ((ResourcelessTransaction) transaction).clear(); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ResourcelessTransactionManagerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ResourcelessTransactionManagerTests.java index b107cc7b2..be5878d24 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ResourcelessTransactionManagerTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ResourcelessTransactionManagerTests.java @@ -16,8 +16,10 @@ package org.springframework.batch.support.transaction; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import org.junit.Test; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionSynchronization; @@ -25,7 +27,7 @@ import org.springframework.transaction.support.TransactionSynchronizationAdapter import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionTemplate; -public class ResourcelessTransactionManagerTests extends TestCase { +public class ResourcelessTransactionManagerTests { private ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager(); @@ -33,6 +35,7 @@ public class ResourcelessTransactionManagerTests extends TestCase { private int count = 0; + @Test public void testCommit() throws Exception { new TransactionTemplate(transactionManager).execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { @@ -48,6 +51,25 @@ public class ResourcelessTransactionManagerTests extends TestCase { assertEquals(TransactionSynchronization.STATUS_COMMITTED, txStatus); } + @Test + public void testCommitTwice() throws Exception { + testCommit(); + txStatus = -1; + new TransactionTemplate(transactionManager).execute(new TransactionCallback() { + public Object doInTransaction(TransactionStatus status) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { + public void afterCompletion(int status) { + super.afterCompletion(status); + txStatus = status; + } + }); + return null; + } + }); + assertEquals(TransactionSynchronization.STATUS_COMMITTED, txStatus); + } + + @Test public void testCommitNested() throws Exception { final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); transactionTemplate.execute(new TransactionCallback() { @@ -74,6 +96,37 @@ public class ResourcelessTransactionManagerTests extends TestCase { assertEquals(2, count); } + @Test + public void testCommitNestedTwice() throws Exception { + testCommitNested(); + count = 0; + txStatus = -1; + final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); + transactionTemplate.execute(new TransactionCallback() { + public Object doInTransaction(TransactionStatus status) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { + public void afterCompletion(int status) { + super.afterCompletion(status); + txStatus = status; + count++; + } + }); + transactionTemplate.execute(new TransactionCallback() { + public Object doInTransaction(TransactionStatus status) { + assertEquals(0, count); + count++; + return null; + } + }); + assertEquals(1, count); + return null; + } + }); + assertEquals(TransactionSynchronization.STATUS_COMMITTED, txStatus); + assertEquals(2, count); + } + + @Test public void testRollback() throws Exception { try { new TransactionTemplate(transactionManager).execute(new TransactionCallback() { @@ -95,6 +148,7 @@ public class ResourcelessTransactionManagerTests extends TestCase { assertEquals(TransactionSynchronization.STATUS_ROLLED_BACK, txStatus); } + @Test public void testRollbackNestedInner() throws Exception { final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); try { @@ -127,6 +181,7 @@ public class ResourcelessTransactionManagerTests extends TestCase { assertEquals(2, count); } + @Test public void testRollbackNestedOuter() throws Exception { final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); try {