You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2018/01/18 17:08:42 UTC

[aries-tx-control] 02/04: tx-control-service spec compliance No Transaction scope should allow post-completion registrations from inside pre-completion callbacks

This is an automated email from the ASF dual-hosted git repository.

timothyjward pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/aries-tx-control.git

commit eb9ec5a5f9aa74464b1c8a327b25cd800ca882d4
Author: Tim Ward <ti...@apache.org>
AuthorDate: Thu Jan 18 16:44:33 2018 +0000

    tx-control-service spec compliance
    No Transaction scope should allow post-completion registrations from inside pre-completion callbacks
---
 .../common/impl/NoTransactionContextImpl.java       | 21 +++++++++++++--------
 .../common/impl/NoTransactionContextTest.java       | 15 +++++++++++++++
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/tx-control-services/tx-control-service-common/src/main/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextImpl.java b/tx-control-services/tx-control-service-common/src/main/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextImpl.java
index aa3d6d0..c345d64 100644
--- a/tx-control-services/tx-control-service-common/src/main/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextImpl.java
+++ b/tx-control-services/tx-control-service-common/src/main/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextImpl.java
@@ -20,7 +20,7 @@ package org.apache.aries.tx.control.service.common.impl;
 
 import static org.osgi.service.transaction.control.TransactionStatus.NO_TRANSACTION;
 
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
 
 import javax.transaction.xa.XAResource;
@@ -32,7 +32,11 @@ import org.osgi.service.transaction.control.TransactionStatus;
 public class NoTransactionContextImpl extends AbstractTransactionContextImpl
 		implements TransactionContext {
 
-	private final AtomicBoolean finished = new AtomicBoolean(false);
+	private enum Status {
+		WORKING, PRE, POST;
+	}
+	
+	private final AtomicReference<Status> status = new AtomicReference<>(Status.WORKING);
 
 	public NoTransactionContextImpl() {
 		super();
@@ -60,9 +64,9 @@ public class NoTransactionContextImpl extends AbstractTransactionContextImpl
 
 	@Override
 	public void preCompletion(Runnable job) throws IllegalStateException {
-		if (finished.get()) {
+		if (status.get() != Status.WORKING) {
 			throw new IllegalStateException(
-					"The transaction context has finished");
+					"The scoped work has returned. No more pre-completion callbacks can be registered");
 		}
 		
 		preCompletion.add(job);
@@ -71,9 +75,9 @@ public class NoTransactionContextImpl extends AbstractTransactionContextImpl
 	@Override
 	public void postCompletion(Consumer<TransactionStatus> job)
 			throws IllegalStateException {
-		if (finished.get()) {
+		if (status.get() == Status.POST) {
 			throw new IllegalStateException(
-					"The transaction context has finished");
+					"Post completion callbacks have begun. No more post-completion callbacks can be registered");
 		}
 
 		postCompletion.add(job);
@@ -106,13 +110,14 @@ public class NoTransactionContextImpl extends AbstractTransactionContextImpl
 
 	@Override
 	protected boolean isAlive() {
-		return !finished.get();
+		return status.get() == Status.WORKING;
 	}
 	
 	@Override
 	public void finish() {
-		if(finished.compareAndSet(false, true)) {
+		if(status.compareAndSet(Status.WORKING, Status.PRE)) {
 			beforeCompletion(() -> {});
+			status.set(Status.POST);
 			afterCompletion(NO_TRANSACTION);
 		}
 	}
diff --git a/tx-control-services/tx-control-service-common/src/test/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextTest.java b/tx-control-services/tx-control-service-common/src/test/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextTest.java
index 4cf4c81..d1e1219 100644
--- a/tx-control-services/tx-control-service-common/src/test/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextTest.java
+++ b/tx-control-services/tx-control-service-common/src/test/java/org/apache/aries/tx/control/service/common/impl/NoTransactionContextTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
+import static org.osgi.service.transaction.control.TransactionStatus.COMMITTED;
 import static org.osgi.service.transaction.control.TransactionStatus.NO_TRANSACTION;
 
 import java.util.concurrent.atomic.AtomicInteger;
@@ -236,6 +237,20 @@ public class NoTransactionContextTest {
 		
 		assertEquals(5, value.get());
 	}
+	
+	@Test
+	public void testPreCompletionRegisterPostCompletion() throws Exception {
+		
+		AtomicInteger value = new AtomicInteger(2);
+		
+		ctx.preCompletion(() -> ctx.postCompletion(t -> value.compareAndSet(1, t.ordinal())));
+		
+		assertEquals(2, value.getAndSet(1));
+		
+		ctx.finish();
+		
+		assertEquals(NO_TRANSACTION.ordinal(), value.get());
+	}
 
 	@Test(expected=IllegalStateException.class)
 	public void testPreCompletionAfterEnd() throws Exception {

-- 
To stop receiving notification emails like this one, please contact
"commits@aries.apache.org" <co...@aries.apache.org>.