[jbosscache-commits] JBoss Cache SVN: r7585 - in core/branches/flat/src: main/java/org/horizon/transaction and 1 other directories.
jbosscache-commits at lists.jboss.org
jbosscache-commits at lists.jboss.org
Fri Jan 23 07:17:27 EST 2009
Author: manik.surtani at jboss.com
Date: 2009-01-23 07:17:27 -0500 (Fri, 23 Jan 2009)
New Revision: 7585
Added:
core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java
Modified:
core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java
core/branches/flat/src/main/java/org/horizon/transaction/TransactionTable.java
Log:
JBCACHE-1468: JBoss Cache ignores transactions with STATUS_MARKED_ROLLBACK and auto commits data changes
Modified: core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java 2009-01-23 12:17:02 UTC (rev 7584)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java 2009-01-23 12:17:27 UTC (rev 7585)
@@ -479,7 +479,7 @@
try {
// JBCACHE-457
VisitableCommand rollbackCommand = commandsFactory.buildRollbackCommand(gtx);
- if (trace) log.trace(" running rollback for " + gtx);
+ if (trace) log.trace(" running rollback for {0}", gtx);
//JBCACHE-359 Store a lookup for the globalTransaction so a listener
// callback can find it
@@ -547,9 +547,15 @@
* Creates a gtx (if one doesnt exist), a sync handler, and registers the tx.
*/
private GlobalTransaction registerTransaction(Transaction tx, InvocationContext ctx) throws Exception {
+ // we have ascertained that the current thread *is* associated with a transaction. We need to make sure the
+ // transaction is in a valid state before moving on, and throwing an exception if not.
+ boolean txValid = TransactionTable.isValid(tx);
+ if (!txValid)
+ throw new IllegalStateException("Transaction " + tx + " is not in a valid state to be invoking cache operations on.");
+
GlobalTransaction gtx;
- if (TransactionTable.isValid(tx) && transactions.add(tx)) {
+ if (transactions.add(tx)) {
gtx = txTable.getCurrentTransaction(tx, true);
TransactionContext transactionContext;
if (ctx.getGlobalTransaction() == null) {
@@ -563,16 +569,16 @@
// should be no need to register a handler since this a remotely initiated globalTransaction
if (trace) log.trace("is a remotely initiated gtx so no need to register a tx for it");
} else {
- if (trace) log.trace("Registering sync handler for tx " + tx + ", gtx " + gtx);
+ if (trace) log.trace("Registering sync handler for tx {0} and gtx {1}", tx, gtx);
// see the comment in the LocalSyncHandler for the last isOriginLocal param.
LocalSynchronizationHandler myHandler = new LocalSynchronizationHandler(gtx, tx, transactionContext, !ctx.isOriginLocal());
registerHandler(tx, myHandler, ctx);
}
} else if ((gtx = rollbackTransactions.get(tx)) != null) {
- if (trace) log.trace("Transaction " + tx + " is already registered and is rolling back.");
+ if (trace) log.trace("Transaction {0} is already registered and is rolling back.", tx);
} else {
- if (trace) log.trace("Transaction " + tx + " is already registered.");
+ if (trace) log.trace("Transaction {0} is already registered.", tx);
}
return gtx;
}
Modified: core/branches/flat/src/main/java/org/horizon/transaction/TransactionTable.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/transaction/TransactionTable.java 2009-01-23 12:17:02 UTC (rev 7584)
+++ core/branches/flat/src/main/java/org/horizon/transaction/TransactionTable.java 2009-01-23 12:17:27 UTC (rev 7585)
@@ -250,13 +250,29 @@
}
/**
- * Return s true of tx's status is ACTIVE or PREPARING
+ * Returns true if transaction is STATUS_MARKED_ROLLBACK, false otherwise
+ */
+ public static boolean isMarkedAsRollback(Transaction tx) {
+ if (tx == null) return false;
+ int status;
+ try {
+ status = tx.getStatus();
+ return status == Status.STATUS_MARKED_ROLLBACK;
+ }
+ catch (SystemException e) {
+ return false;
+ }
+ }
+
+
+ /**
+ * Return s true of tx's status is ACTIVE or PREPARING or MARKED_ROLLBACK
*
* @param tx
* @return true if the tx is active or preparing
*/
public static boolean isValid(Transaction tx) {
- return isActive(tx) || isPreparing(tx);
+ return isActive(tx) || isPreparing(tx) || isMarkedAsRollback(tx);
}
/**
Added: core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java 2009-01-23 12:17:27 UTC (rev 7585)
@@ -0,0 +1,73 @@
+package org.horizon.tx;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.horizon.CacheSPI;
+import org.horizon.UnitTestCacheFactory;
+import org.horizon.config.Configuration;
+import org.horizon.transaction.DummyTransactionManagerLookup;
+import org.horizon.util.TestingUtil;
+import org.testng.annotations.Test;
+
+import javax.transaction.RollbackException;
+import javax.transaction.TransactionManager;
+
+ at Test(groups = "functional")
+public class MarkAsRollbackTest {
+ private static final Log log = LogFactory.getLog(MarkAsRollbackTest.class);
+
+ public void testMarkAsRollbackAfterMods() throws Exception {
+ Configuration c = new Configuration();
+ c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+ CacheSPI<String, String> cache = (CacheSPI<String, String>) new UnitTestCacheFactory<String, String>().createCache(c);
+ try {
+ TransactionManager tm = cache.getTransactionManager();
+ assert tm != null;
+ tm.begin();
+ cache.put("k", "v");
+ assert cache.get("k").equals("v");
+ tm.setRollbackOnly();
+ try {
+ tm.commit();
+ assert false : "Should have rolled back";
+ }
+ catch (RollbackException expected) {
+ }
+
+ assert tm.getTransaction() == null : "There should be no transaction in scope anymore!";
+ assert cache.get("k") == null : "Expected a null but was " + cache.get("k");
+ }
+ finally {
+ log.warn("Cleaning up");
+ TestingUtil.killCaches(cache);
+ }
+ }
+
+ public void testMarkAsRollbackBeforeMods() throws Exception {
+ Configuration c = new Configuration();
+ c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+ CacheSPI<String, String> cache = (CacheSPI<String, String>) new UnitTestCacheFactory<String, String>().createCache(c);
+ try {
+ TransactionManager tm = cache.getTransactionManager();
+ assert tm != null;
+ tm.begin();
+ tm.setRollbackOnly();
+ cache.put("k", "v");
+ assert cache.get("k").equals("v");
+ try {
+ tm.commit();
+ assert false : "Should have rolled back";
+ }
+ catch (RollbackException expected) {
+
+ }
+
+ assert tm.getTransaction() == null : "There should be no transaction in scope anymore!";
+ assert cache.get("k") == null : "Expected a null but was " + cache.get("k");
+ }
+ finally {
+ log.warn("Cleaning up");
+ TestingUtil.killCaches(cache);
+ }
+ }
+}
More information about the jbosscache-commits
mailing list