[infinispan-commits] Infinispan SVN: r252 - in trunk: core/src/main/java/org/infinispan/atomic and 60 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Mon May 11 22:58:06 EDT 2009
Author: mircea.markus
Date: 2009-05-11 22:58:05 -0400 (Mon, 11 May 2009)
New Revision: 252
Added:
trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/
trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMap.java
trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapDelta.java
trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapProxy.java
trunk/core/src/main/java/org/infinispan/atomic/operations/
trunk/core/src/main/java/org/infinispan/atomic/operations/ClearOperation.java
trunk/core/src/main/java/org/infinispan/atomic/operations/PutOperation.java
trunk/core/src/main/java/org/infinispan/atomic/operations/RemoveOperation.java
trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java
trunk/core/src/main/java/org/infinispan/context/container/
trunk/core/src/main/java/org/infinispan/context/container/InvocationContextContainer.java
trunk/core/src/main/java/org/infinispan/context/container/ReplicationInvocationContextContainer.java
trunk/core/src/main/java/org/infinispan/context/impl/
trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java
trunk/core/src/main/java/org/infinispan/context/impl/InitiatorTxInvocationContext.java
trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java
trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java
trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java
trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
trunk/core/src/main/java/org/infinispan/loader/
trunk/core/src/main/java/org/infinispan/lock/
trunk/core/src/main/java/org/infinispan/remoting/rpc/
trunk/core/src/main/java/org/infinispan/remoting/rpc/CacheRpcManager.java
trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseFilter.java
trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseMode.java
trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManager.java
trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManagerImpl.java
trunk/core/src/main/java/org/infinispan/transaction/lookup/
trunk/core/src/main/java/org/infinispan/transaction/lookup/DummyTransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/lookup/GenericTransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossStandaloneJTAManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossTransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/lookup/TransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/tm/
trunk/core/src/main/java/org/infinispan/transaction/tm/BatchModeTransactionManager.java
trunk/core/src/main/java/org/infinispan/transaction/tm/DummyBaseTransactionManager.java
trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransaction.java
trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransactionManager.java
trunk/core/src/main/java/org/infinispan/transaction/tm/DummyUserTransaction.java
trunk/core/src/main/java/org/infinispan/transaction/tm/DummyXid.java
trunk/core/src/main/java/org/infinispan/transaction/xa/
trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java
trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java
trunk/core/src/main/java/org/infinispan/transaction/xa/TxEnlistingManager.java
Removed:
trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java
trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java
trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java
trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java
trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java
trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java
trunk/core/src/main/java/org/infinispan/commands/TransactionBoundaryCommand.java
trunk/core/src/main/java/org/infinispan/context/AbstractContext.java
trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java
trunk/core/src/main/java/org/infinispan/context/InvocationContextContainer.java
trunk/core/src/main/java/org/infinispan/context/InvocationContextImpl.java
trunk/core/src/main/java/org/infinispan/context/TransactionContext.java
trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java
trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java
trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java
trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java
trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java
trunk/core/src/main/java/org/infinispan/interceptors/BaseTransactionalContextInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
trunk/core/src/main/java/org/infinispan/remoting/ResponseFilter.java
trunk/core/src/main/java/org/infinispan/remoting/ResponseMode.java
trunk/core/src/main/java/org/infinispan/remoting/RpcManager.java
trunk/core/src/main/java/org/infinispan/remoting/RpcManagerImpl.java
trunk/core/src/main/java/org/infinispan/transaction/BatchModeTransactionManager.java
trunk/core/src/main/java/org/infinispan/transaction/DummyBaseTransactionManager.java
trunk/core/src/main/java/org/infinispan/transaction/DummyTransaction.java
trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManager.java
trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/DummyUserTransaction.java
trunk/core/src/main/java/org/infinispan/transaction/GenericTransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/GlobalTransaction.java
trunk/core/src/main/java/org/infinispan/transaction/JBossStandaloneJTAManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/JBossTransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/TransactionManagerLookup.java
trunk/core/src/main/java/org/infinispan/transaction/TransactionTable.java
Modified:
trunk/core/src/main/java/org/infinispan/AbstractDelegatingAdvancedCache.java
trunk/core/src/main/java/org/infinispan/AdvancedCache.java
trunk/core/src/main/java/org/infinispan/CacheDelegate.java
trunk/core/src/main/java/org/infinispan/atomic/AtomicMap.java
trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java
trunk/core/src/main/java/org/infinispan/batch/BatchContainer.java
trunk/core/src/main/java/org/infinispan/commands/AbstractVisitor.java
trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java
trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
trunk/core/src/main/java/org/infinispan/commands/RemoteCommandFactory.java
trunk/core/src/main/java/org/infinispan/commands/ReplicableCommand.java
trunk/core/src/main/java/org/infinispan/commands/Visitor.java
trunk/core/src/main/java/org/infinispan/commands/control/StateTransferControlCommand.java
trunk/core/src/main/java/org/infinispan/commands/remote/BaseRpcCommand.java
trunk/core/src/main/java/org/infinispan/commands/remote/CacheRpcCommand.java
trunk/core/src/main/java/org/infinispan/commands/remote/ClusteredGetCommand.java
trunk/core/src/main/java/org/infinispan/commands/remote/MultipleRpcCommand.java
trunk/core/src/main/java/org/infinispan/commands/remote/SingleRpcCommand.java
trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java
trunk/core/src/main/java/org/infinispan/commands/tx/CommitCommand.java
trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
trunk/core/src/main/java/org/infinispan/commands/tx/RollbackCommand.java
trunk/core/src/main/java/org/infinispan/config/Configuration.java
trunk/core/src/main/java/org/infinispan/config/RuntimeConfig.java
trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java
trunk/core/src/main/java/org/infinispan/context/EntryLookup.java
trunk/core/src/main/java/org/infinispan/context/InvocationContext.java
trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java
trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java
trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorFactory.java
trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java
trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java
trunk/core/src/main/java/org/infinispan/factories/RpcManagerFactory.java
trunk/core/src/main/java/org/infinispan/factories/TransactionManagerFactory.java
trunk/core/src/main/java/org/infinispan/interceptors/BatchingInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/CacheLoaderInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/CacheStoreInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/DistTxInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/InterceptorChain.java
trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/NotificationInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/ReplicationInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java
trunk/core/src/main/java/org/infinispan/interceptors/base/PrePostProcessingCommandInterceptor.java
trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java
trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java
trunk/core/src/main/java/org/infinispan/marshall/MarshalledValue.java
trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java
trunk/core/src/main/java/org/infinispan/notifications/Listener.java
trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifier.java
trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifierImpl.java
trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/EventImpl.java
trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/TransactionalEvent.java
trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandler.java
trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java
trunk/core/src/main/java/org/infinispan/remoting/ReplicationQueue.java
trunk/core/src/main/java/org/infinispan/remoting/responses/ClusteredGetResponseValidityFilter.java
trunk/core/src/main/java/org/infinispan/remoting/transport/Transport.java
trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsResponseFilterAdapter.java
trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java
trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java
trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java
trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManager.java
trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManagerImpl.java
trunk/core/src/main/java/org/infinispan/util/concurrent/locks/OwnableReentrantLock.java
trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java
trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java
trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/ReentrantStripedLockContainer.java
trunk/core/src/main/resources/config-samples/all.xml
trunk/core/src/test/java/org/infinispan/api/CacheAPITest.java
trunk/core/src/test/java/org/infinispan/api/batch/BatchWithTMTest.java
trunk/core/src/test/java/org/infinispan/api/mvcc/LockAssert.java
trunk/core/src/test/java/org/infinispan/api/mvcc/LockPerEntryTest.java
trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java
trunk/core/src/test/java/org/infinispan/api/mvcc/PutForExternalReadTest.java
trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/RepeatableReadLockTest.java
trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/WriteSkewTest.java
trunk/core/src/test/java/org/infinispan/atomic/APITest.java
trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java
trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java
trunk/core/src/test/java/org/infinispan/atomic/AtomicMapFunctionalTest.java
trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java
trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java
trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java
trunk/core/src/test/java/org/infinispan/distribution/BaseDistFunctionalTest.java
trunk/core/src/test/java/org/infinispan/distribution/DistSyncFuncTest.java
trunk/core/src/test/java/org/infinispan/distribution/DistSyncTxFuncTest.java
trunk/core/src/test/java/org/infinispan/invalidation/BaseInvalidationTest.java
trunk/core/src/test/java/org/infinispan/jmx/MvccLockManagerMBeanTest.java
trunk/core/src/test/java/org/infinispan/jmx/RpcManagerMBeanTest.java
trunk/core/src/test/java/org/infinispan/jmx/TxInterceptorMBeanTest.java
trunk/core/src/test/java/org/infinispan/loaders/CacheLoaderFunctionalTest.java
trunk/core/src/test/java/org/infinispan/loaders/PassivationFunctionalTest.java
trunk/core/src/test/java/org/infinispan/manager/CacheManagerComponentRegistryTest.java
trunk/core/src/test/java/org/infinispan/manager/CacheManagerXmlConfigurationTest.java
trunk/core/src/test/java/org/infinispan/marshall/MarshalledValueTest.java
trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java
trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java
trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java
trunk/core/src/test/java/org/infinispan/replication/AsyncReplTest.java
trunk/core/src/test/java/org/infinispan/replication/BaseReplicatedAPITest.java
trunk/core/src/test/java/org/infinispan/replication/ReplicationExceptionTest.java
trunk/core/src/test/java/org/infinispan/replication/ReplicationQueueTest.java
trunk/core/src/test/java/org/infinispan/replication/SyncCacheListenerTest.java
trunk/core/src/test/java/org/infinispan/replication/SyncReplTest.java
trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferCacheLoaderFunctionalTest.java
trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferFunctionalTest.java
trunk/core/src/test/java/org/infinispan/test/AbstractCacheTest.java
trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java
trunk/core/src/test/java/org/infinispan/test/ReplListener.java
trunk/core/src/test/java/org/infinispan/test/TestingUtil.java
trunk/core/src/test/java/org/infinispan/tx/LocalModeTxTest.java
trunk/core/src/test/java/org/infinispan/tx/MarkAsRollbackTest.java
trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningCaches.java
trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningReplicatedCaches.java
trunk/core/src/test/resources/configs/named-cache-test.xml
trunk/core/src/test/resources/configs/string-property-replaced.xml
trunk/tree/src/main/java/org/infinispan/tree/NodeImpl.java
trunk/tree/src/main/java/org/infinispan/tree/TreeCacheImpl.java
trunk/tree/src/main/java/org/infinispan/tree/TreeStructureSupport.java
trunk/tree/src/test/java/org/infinispan/api/tree/NodeAPITest.java
trunk/tree/src/test/java/org/infinispan/api/tree/NodeLockSupport.java
trunk/tree/src/test/java/org/infinispan/api/tree/NodeMoveAPITest.java
trunk/tree/src/test/java/org/infinispan/api/tree/NodeReplicatedMoveTest.java
trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTest.java
trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTxTest.java
trunk/tree/src/test/java/org/infinispan/api/tree/TreeCacheAPITest.java
trunk/tree/src/test/java/org/infinispan/profiling/TreeProfileTest.java
Log:
tx related refactoring
Modified: trunk/core/src/main/java/org/infinispan/AbstractDelegatingAdvancedCache.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/AbstractDelegatingAdvancedCache.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/AbstractDelegatingAdvancedCache.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -3,11 +3,11 @@
import org.infinispan.batch.BatchContainer;
import org.infinispan.container.DataContainer;
import org.infinispan.context.Flag;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.eviction.EvictionManager;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import java.util.Collection;
import java.util.List;
Modified: trunk/core/src/main/java/org/infinispan/AdvancedCache.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/AdvancedCache.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/AdvancedCache.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -3,11 +3,11 @@
import org.infinispan.batch.BatchContainer;
import org.infinispan.container.DataContainer;
import org.infinispan.context.Flag;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.eviction.EvictionManager;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import java.util.Collection;
import java.util.List;
Modified: trunk/core/src/main/java/org/infinispan/CacheDelegate.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/CacheDelegate.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/CacheDelegate.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,9 +21,9 @@
*/
package org.infinispan;
-import org.infinispan.atomic.AtomicHashMap;
import org.infinispan.atomic.AtomicMap;
import org.infinispan.atomic.AtomicMapCache;
+import org.infinispan.atomic.atomichashmap.AtomicHashMap;
import org.infinispan.batch.BatchContainer;
import org.infinispan.commands.CommandsFactory;
import org.infinispan.commands.read.GetKeyValueCommand;
@@ -40,7 +40,7 @@
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.eviction.EvictionManager;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.factories.annotations.Inject;
@@ -52,8 +52,8 @@
import org.infinispan.marshall.MarshalledValue;
import org.infinispan.marshall.Marshaller;
import org.infinispan.notifications.cachelistener.CacheNotifier;
-import org.infinispan.remoting.RpcManager;
import org.infinispan.remoting.responses.ResponseGenerator;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.statetransfer.StateTransferManager;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -74,7 +74,7 @@
*/
@NonVolatile
public class CacheDelegate<K, V> implements AdvancedCache<K, V>, AtomicMapCache<K, V> {
- protected InvocationContextContainer invocationContextContainer;
+ protected InvocationContextContainer icc;
protected CommandsFactory commandsFactory;
protected InterceptorChain invoker;
protected Configuration config;
@@ -101,7 +101,7 @@
@Inject
public void injectDependencies(EvictionManager evictionManager,
- InvocationContextContainer invocationContextContainer,
+ InvocationContextContainer icc,
CommandsFactory commandsFactory,
InterceptorChain interceptorChain,
Configuration configuration,
@@ -112,7 +112,6 @@
RpcManager rpcManager, DataContainer dataContainer,
Marshaller marshaller, ResponseGenerator responseGenerator,
CacheManager cacheManager, StateTransferManager stateTransferManager) {
- this.invocationContextContainer = invocationContextContainer;
this.commandsFactory = commandsFactory;
this.invoker = interceptorChain;
this.config = configuration;
@@ -127,6 +126,7 @@
this.cacheManager = cacheManager;
this.responseGenerator = responseGenerator;
this.stateTransferManager = stateTransferManager;
+ this.icc = icc;
}
@SuppressWarnings("unchecked")
@@ -208,25 +208,7 @@
}
public void putForExternalRead(K key, V value) {
- Transaction ongoingTransaction = null;
- try {
- if (transactionManager != null && (ongoingTransaction = transactionManager.getTransaction()) != null) {
- transactionManager.suspend();
- }
- // if the entry exists then this should be a no-op.
- putIfAbsent(key, value, Flag.FAIL_SILENTLY, Flag.FORCE_ASYNCHRONOUS, Flag.ZERO_LOCK_ACQUISITION_TIMEOUT);
- }
- catch (Exception e) {
- if (log.isDebugEnabled()) log.debug("Caught exception while doing putForExternalRead()", e);
- }
- finally {
- try {
- if (ongoingTransaction != null) transactionManager.resume(ongoingTransaction);
- }
- catch (Exception e) {
- log.debug("Had problems trying to resume a transaction after putForExternalread()", e);
- }
- }
+ putForExternalRead(key, value, null);
}
public void evict(K key) {
@@ -251,9 +233,9 @@
}
private InvocationContext getInvocationContext() {
- return invocationContextContainer.get();
+ return icc.getLocalInvocationContext(true);
}
-
+
public void lock(K key, boolean eager) {
// TODO: Customise this generated block
}
@@ -313,48 +295,88 @@
}
public void putForExternalRead(K key, V value, Flag... flags) {
- getInvocationContext().setFlags(flags);
- putForExternalRead(key, value);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ Transaction ongoingTransaction = null;
+ try {
+ if (transactionManager != null && (ongoingTransaction = transactionManager.getTransaction()) != null) {
+ transactionManager.suspend();
+ }
+ // if the entry exists then this should be a no-op.
+ putIfAbsent(key, value, Flag.FAIL_SILENTLY, Flag.FORCE_ASYNCHRONOUS, Flag.ZERO_LOCK_ACQUISITION_TIMEOUT);
+ }
+ catch (Exception e) {
+ if (log.isDebugEnabled()) log.debug("Caught exception while doing putForExternalRead()", e);
+ }
+ finally {
+ try {
+ if (ongoingTransaction != null) transactionManager.resume(ongoingTransaction);
+ }
+ catch (Exception e) {
+ log.debug("Had problems trying to resume a transaction after putForExternalread()", e);
+ }
+ }
}
public V put(K key, V value, Flag... flags) {
- getInvocationContext().setFlags(flags);
- return put(key, value, defaultLifespan, MILLISECONDS, defaultMaxIdleTime, MILLISECONDS);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(key, value, MILLISECONDS.toMillis(defaultLifespan), MILLISECONDS.toMillis(defaultMaxIdleTime));
+ return (V) invoker.invoke(invocationContext, command);
}
public V put(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit, Flag... flags) {
- getInvocationContext().setFlags(flags);
- return put(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(key, value, lifespanUnit.toMillis(lifespan), maxIdleTimeUnit.toMillis(maxIdleTime));
+ return (V) invoker.invoke(invocationContext, command);
}
public V putIfAbsent(K key, V value, Flag... flags) {
- getInvocationContext().setFlags(flags);
- return putIfAbsent(key, value, defaultLifespan, MILLISECONDS, defaultMaxIdleTime, MILLISECONDS);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(key, value, MILLISECONDS.toMillis(defaultLifespan), MILLISECONDS.toMillis(defaultMaxIdleTime));
+ command.setPutIfAbsent(true);
+ return (V) invoker.invoke(invocationContext, command);
}
public V putIfAbsent(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit, Flag... flags) {
- getInvocationContext().setFlags(flags);
- return putIfAbsent(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ return putIfAbsent(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit, flags);
}
public void putAll(Map<? extends K, ? extends V> map, Flag... flags) {
- getInvocationContext().setFlags(flags);
- putAll(map, defaultLifespan, MILLISECONDS, defaultMaxIdleTime, MILLISECONDS);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ PutMapCommand command = commandsFactory.buildPutMapCommand(map, MILLISECONDS.toMillis(defaultLifespan), MILLISECONDS.toMillis(defaultMaxIdleTime));
+ invoker.invoke(invocationContext, command);
}
public void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit, Flag... flags) {
- getInvocationContext().setFlags(flags);
- putAll(map, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ PutMapCommand command = commandsFactory.buildPutMapCommand(map, lifespanUnit.toMillis(lifespan), maxIdleTimeUnit.toMillis(maxIdleTime));
+ invoker.invoke(invocationContext, command);
}
public V remove(Object key, Flag... flags) {
- getInvocationContext().setFlags(flags);
- return remove(key);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ RemoveCommand command = commandsFactory.buildRemoveCommand(key, null);
+ return (V) invoker.invoke(invocationContext, command);
}
+ public boolean remove(Object key, Object oldValue, Flag... flags) {
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ RemoveCommand command = commandsFactory.buildRemoveCommand(key, oldValue);
+ return (Boolean) invoker.invoke(invocationContext, command);
+ }
+
public void clear(Flag... flags) {
- getInvocationContext().setFlags(flags);
- clear();
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ ClearCommand command = commandsFactory.buildClearCommand();
+ invoker.invoke(invocationContext, command);
}
public V replace(K k, V v, Flag... flags) {
@@ -422,13 +444,18 @@
}
public boolean containsKey(Object key, Flag... flags) {
- getInvocationContext().setFlags(flags);
- return containsKey(key);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ GetKeyValueCommand command = commandsFactory.buildGetKeyValueCommand(key);
+ Object response = invoker.invoke(invocationContext, command);
+ return response != null;
}
public V get(Object key, Flag... flags) {
- getInvocationContext().setFlags(flags);
- return get(key);
+ InvocationContext invocationContext = getInvocationContext();
+ invocationContext.setFlags(flags);
+ GetKeyValueCommand command = commandsFactory.buildGetKeyValueCommand(key);
+ return (V) invoker.invoke(invocationContext, command);
}
public ComponentStatus getStatus() {
@@ -464,7 +491,7 @@
public <AMK, AMV> AtomicMap<AMK, AMV> getAtomicMap(K key) throws ClassCastException {
Object value = get(key);
if (value == null) value = AtomicHashMap.newInstance(this, key);
- return ((AtomicHashMap) value).getProxy(this, key, batchContainer, invocationContextContainer);
+ return ((AtomicHashMap) value).getProxy(this, key, batchContainer, icc);
}
public BatchContainer getBatchContainer() {
@@ -472,7 +499,7 @@
}
public InvocationContextContainer getInvocationContextContainer() {
- return invocationContextContainer;
+ return icc;
}
public DataContainer getDataContainer() {
Deleted: trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,176 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.atomic;
-
-import net.jcip.annotations.NotThreadSafe;
-import org.infinispan.Cache;
-import org.infinispan.batch.BatchContainer;
-import org.infinispan.context.InvocationContextContainer;
-import org.infinispan.util.FastCopyHashMap;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Note that for replication to work properly, this class <b><i>requires</i></b> that all writes take place within the
- * scope of an ongoing transaction or batch.
- * <p/>
- *
- * @author (various)
- * @param <K>
- * @param <V>
- * @since 4.0
- */
- at NotThreadSafe
-public class AtomicHashMap<K, V> implements AtomicMap<K, V>, DeltaAware, Cloneable {
- FastCopyHashMap<K, V> delegate;
- AtomicHashMapDelta delta = null;
- volatile AtomicHashMapProxy proxy;
-
- /**
- * Construction only allowed through this factory method. This factory is intended for use internally by the
- * CacheDelegate. User code should use {@link AtomicMapCache#getAtomicMap(Object)}.
- */
- public static AtomicHashMap newInstance(Cache cache, Object cacheKey) {
- AtomicHashMap value = new AtomicHashMap();
- Object oldValue = cache.putIfAbsent(cacheKey, value);
- if (oldValue != null) value = (AtomicHashMap) oldValue;
- return value;
- }
-
- AtomicHashMap() {
- delegate = new FastCopyHashMap<K, V>();
- }
-
- public void commit() {
- if (delta != null) delta = null;
- }
-
- public int size() {
- return delegate.size();
- }
-
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- public boolean containsKey(Object key) {
- return delegate.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- return delegate.containsValue(value);
- }
-
- public V get(Object key) {
- return delegate.get(key);
- }
-
- public V put(K key, V value) {
- PutOperation<K, V> op = new PutOperation<K, V>();
- op.key = key;
- op.newValue = value;
- op.oldValue = delegate.put(key, value);
- delta.addOperation(op);
- return op.oldValue;
- }
-
- public V remove(Object key) {
- RemoveOperation<K, V> op = new RemoveOperation<K, V>();
- op.key = (K) key;
- op.oldValue = delegate.remove(key);
- delta.addOperation(op);
- return op.oldValue;
- }
-
- public void putAll(Map<? extends K, ? extends V> t) {
- // this is crappy - need to do this more efficiently!
- for (Entry<? extends K, ? extends V> e : t.entrySet()) put(e.getKey(), e.getValue());
- }
-
- public void clear() {
- ClearOperation<K, V> op = new ClearOperation<K, V>();
- op.originalEntries = (FastCopyHashMap<K, V>) delegate.clone();
- delta.addOperation(op);
- delegate.clear();
- }
-
- public Set<K> keySet() {
- return delegate.keySet();
- }
-
- public Collection<V> values() {
- return delegate.values();
- }
-
- public Set<Entry<K, V>> entrySet() {
- return delegate.entrySet();
- }
-
- public AtomicMap getProxy(Cache cache, Object mapKey,
- BatchContainer batchContainer, InvocationContextContainer invocationContextContainer) {
- // construct the proxy lazily
- if (proxy == null) // DCL is OK here since proxy is volatile (and we live in a post-JDK 5 world)
- {
- synchronized (this) {
- if (proxy == null)
- proxy = new AtomicHashMapProxy(cache, mapKey, batchContainer, invocationContextContainer);
- }
- }
- return proxy;
- }
-
- public Delta delta() {
-
- Delta toReturn = delta == null ? NullDelta.INSTANCE : delta;
- delta = null; // reset
- return toReturn;
- }
-
- public AtomicHashMap copyForWrite() {
- try {
- AtomicHashMap clone = (AtomicHashMap) super.clone();
- clone.delegate = (FastCopyHashMap) delegate.clone();
- clone.proxy = proxy;
- return clone;
- }
- catch (CloneNotSupportedException e) {
- // should never happen!!
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String toString() {
- return "AtomicHashMap{" +
- "delegate=" + delegate +
- '}';
- }
-
- /**
- * Initializes the delta instance to start recording changes.
- */
- public void initForWriting() {
- delta = new AtomicHashMapDelta();
- }
-}
Deleted: trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,84 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.atomic;
-
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Changes that have occured on an AtomicHashMap
- *
- * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
- * @since 4.0
- */
-public class AtomicHashMapDelta implements Delta {
- private List<Operation> changelog;
- private static final Log log = LogFactory.getLog(AtomicHashMapDelta.class);
- private static final boolean trace = log.isTraceEnabled();
-
- public DeltaAware merge(DeltaAware d) {
- AtomicHashMap other;
- if (d != null && (d instanceof AtomicHashMap))
- other = (AtomicHashMap) d;
- else
- other = new AtomicHashMap();
-
- for (Operation o : changelog) o.replay(other.delegate);
- other.commit();
- return other;
- }
-
- public void addOperation(Operation o) {
- if (changelog == null) {
- // lazy init
- changelog = new LinkedList<Operation>();
- }
- changelog.add(o);
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- if (trace) log.trace("Serializing changelog " + changelog);
- out.writeObject(changelog);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- changelog = (List<Operation>) in.readObject();
- if (trace) log.trace("Deserialized changelog " + changelog);
- }
-
- @Override
- public String toString() {
- return "AtomicHashMapDelta{" +
- "changelog=" + changelog +
- '}';
- }
-
- public int getChangeLogSize() {
- return changelog == null ? 0 : changelog.size();
- }
-}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,173 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.atomic;
-
-import org.infinispan.Cache;
-import org.infinispan.batch.AutoBatchSupport;
-import org.infinispan.batch.BatchContainer;
-import org.infinispan.context.Flag;
-import org.infinispan.context.InvocationContextContainer;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A layer of indirection around an {@link org.infinispan.atomic.AtomicHashMap} to provide reader consistency
- *
- * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
- * @since 4.0
- */
-public class AtomicHashMapProxy<K, V> extends AutoBatchSupport implements AtomicMap<K, V> {
- private static final Log log = LogFactory.getLog(AtomicHashMapProxy.class);
- private static final boolean trace = log.isTraceEnabled();
- Object deltaMapKey;
- Cache cache;
- InvocationContextContainer icc;
-
- public AtomicHashMapProxy(Cache cache, Object deltaMapKey, BatchContainer batchContainer, InvocationContextContainer icc) {
- this.cache = cache;
- this.deltaMapKey = deltaMapKey;
- this.batchContainer = batchContainer;
- this.icc = icc;
- }
-
- // internal helper, reduces lots of casts.
- private AtomicHashMap<K, V> getDeltaMapForRead() {
- return (AtomicHashMap<K, V>) cache.get(deltaMapKey);
- }
-
- private AtomicHashMap<K, V> getDeltaMapForWrite() {
- if (ownsLock()) {
- return (AtomicHashMap<K, V>) cache.get(deltaMapKey);
- } else {
- // acquire WL
- boolean suppressLocks = icc.get().hasFlag(Flag.SKIP_LOCKING);
- if (!suppressLocks) icc.get().setFlags(Flag.FORCE_WRITE_LOCK);
-
- if (trace) {
- if (suppressLocks)
- log.trace("Skip locking flag used. Skipping locking.");
- else
- log.trace("Forcing write lock even for reads");
- }
-
- AtomicHashMap map = getDeltaMapForRead();
- // copy for write
- AtomicHashMap copy = map == null ? new AtomicHashMap() : map.copyForWrite();
- copy.initForWriting();
- // reinstate the flag
- if (suppressLocks) icc.get().setFlags(Flag.SKIP_LOCKING);
- cache.put(deltaMapKey, copy);
- return copy;
- }
- }
-
- private boolean ownsLock() {
- return icc.get().hasLockedKey(deltaMapKey);
- }
-
- // readers
-
- public Set<K> keySet() {
- return getDeltaMapForRead().keySet();
- }
-
- public Collection<V> values() {
- return getDeltaMapForRead().values();
- }
-
- public Set<Entry<K, V>> entrySet() {
- return getDeltaMapForRead().entrySet();
- }
-
- public int size() {
- return getDeltaMapForRead().size();
- }
-
- public boolean isEmpty() {
- return getDeltaMapForRead().isEmpty();
- }
-
- public boolean containsKey(Object key) {
- return getDeltaMapForRead().containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- return getDeltaMapForRead().containsValue(value);
- }
-
- public V get(Object key) {
- return getDeltaMapForRead().get(key);
- }
-
- // writers
-
- public V put(K key, V value) {
- try {
- startAtomic();
- return getDeltaMapForWrite().put(key, value);
- }
- finally {
- endAtomic();
- }
- }
-
- public V remove(Object key) {
- try {
- startAtomic();
- return getDeltaMapForWrite().remove(key);
- }
- finally {
- endAtomic();
- }
- }
-
- public void putAll(Map<? extends K, ? extends V> m) {
- try {
- startAtomic();
- getDeltaMapForWrite().putAll(m);
- }
- finally {
- endAtomic();
- }
- }
-
- public void clear() {
- try {
- startAtomic();
- getDeltaMapForWrite().clear();
- }
- finally {
- endAtomic();
- }
- }
-
- @Override
- public String toString() {
- return "AtomicHashMapProxy{" +
- "deltaMapKey=" + deltaMapKey +
- '}';
- }
-}
Modified: trunk/core/src/main/java/org/infinispan/atomic/AtomicMap.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/AtomicMap.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/AtomicMap.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -34,7 +34,7 @@
*
* @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
* @see DeltaAware
- * @see AtomicHashMap
+ * @see org.infinispan.atomic.atomichashmap.AtomicHashMap
* @since 4.0
*/
public interface AtomicMap<K, V> extends Map<K, V> {
Deleted: trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,39 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.atomic;
-
-import org.infinispan.util.FastCopyHashMap;
-
-import java.util.Map;
-
-
-public class ClearOperation<K, V> extends Operation<K, V> {
- FastCopyHashMap<K, V> originalEntries;
-
- public void rollback(Map<K, V> delegate) {
- if (!originalEntries.isEmpty()) delegate.putAll(originalEntries);
- }
-
- public void replay(Map<K, V> delegate) {
- delegate.clear();
- }
-}
\ No newline at end of file
Modified: trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/NullDelta.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,7 +21,8 @@
*/
package org.infinispan.atomic;
-import java.io.Externalizable;
+import org.infinispan.atomic.atomichashmap.AtomicHashMap;
+
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
@@ -32,8 +33,8 @@
* @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
* @since 4.0
*/
-public class NullDelta implements Externalizable, Delta {
- static final NullDelta INSTANCE = new NullDelta();
+public class NullDelta implements Delta {
+ public static final NullDelta INSTANCE = new NullDelta();
public void writeExternal(ObjectOutput out) throws IOException {
// don't bother writing anything
@@ -43,7 +44,7 @@
// nothing to read
}
- public DeltaAware merge(DeltaAware d) {
- return (d != null && d instanceof AtomicHashMap) ? d : new AtomicHashMap();
+ public DeltaAware merge(DeltaAware other) {
+ return (other != null && other instanceof AtomicHashMap) ? other : new AtomicHashMap();
}
}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,58 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.atomic;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.Map;
-
-
-public class PutOperation<K, V> extends Operation<K, V> {
- K key;
- V oldValue;
- V newValue;
-
- public void rollback(Map<K, V> delegate) {
- if (oldValue == null)
- delegate.remove(key);
- else
- delegate.put(key, oldValue);
- }
-
- public void replay(Map<K, V> delegate) {
- delegate.put(key, newValue);
- }
-
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- // don't bother writing out the old value since it will never be rolled back
- out.writeObject(key);
- out.writeObject(newValue);
- }
-
- @Override
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- key = (K) in.readObject();
- newValue = (V) in.readObject();
- }
-}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,51 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.atomic;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.Map;
-
-
-public class RemoveOperation<K, V> extends Operation<K, V> {
- K key;
- V oldValue;
-
- public void rollback(Map<K, V> delegate) {
- if (oldValue != null) delegate.put(key, oldValue);
- }
-
- public void replay(Map<K, V> delegate) {
- delegate.remove(key);
- }
-
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(key);
- }
-
- @Override
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- key = (K) in.readObject();
- }
-}
\ No newline at end of file
Copied: trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMap.java (from rev 208, trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMap.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMap.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMap.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,184 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.atomic.atomichashmap;
+
+import net.jcip.annotations.NotThreadSafe;
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.atomic.DeltaAware;
+import org.infinispan.atomic.operations.PutOperation;
+import org.infinispan.atomic.operations.RemoveOperation;
+import org.infinispan.atomic.operations.ClearOperation;
+import org.infinispan.atomic.Delta;
+import org.infinispan.atomic.NullDelta;
+import org.infinispan.batch.BatchContainer;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.util.FastCopyHashMap;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Note that for replication to work properly, this class <b><i>requires</i></b> that all writes take place within the
+ * scope of an ongoing transaction or batch.
+ * <p/>
+ *
+ * @author (various)
+ * @param <K>
+ * @param <V>
+ * @since 4.0
+ */
+ at NotThreadSafe
+public class AtomicHashMap<K, V> implements AtomicMap<K, V>, DeltaAware, Cloneable {
+ FastCopyHashMap<K, V> delegate;
+ private AtomicHashMapDelta delta = null;
+ private volatile AtomicHashMapProxy proxy;
+
+ /**
+ * Construction only allowed through this factory method. This factory is intended for use internally by the
+ * CacheDelegate. User code should use {@link org.infinispan.atomic.AtomicMapCache#getAtomicMap(Object)}.
+ */
+ public static AtomicHashMap newInstance(Cache cache, Object cacheKey) {
+ AtomicHashMap value = new AtomicHashMap();
+ Object oldValue = cache.putIfAbsent(cacheKey, value);
+ if (oldValue != null) value = (AtomicHashMap) oldValue;
+ return value;
+ }
+
+ public AtomicHashMap() {
+ delegate = new FastCopyHashMap<K, V>();
+ }
+
+ public void commit() {
+ if (delta != null) delta = null;
+ }
+
+ public int size() {
+ return delegate.size();
+ }
+
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ public boolean containsKey(Object key) {
+ return delegate.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return delegate.containsValue(value);
+ }
+
+ public V get(Object key) {
+ return delegate.get(key);
+ }
+
+ public Set<K> keySet() {
+ return delegate.keySet();
+ }
+
+ public Collection<V> values() {
+ return delegate.values();
+ }
+
+ public Set<Entry<K, V>> entrySet() {
+ return delegate.entrySet();
+ }
+
+ public V put(K key, V value) {
+ V oldValue = delegate.put(key, value);
+ PutOperation<K, V> op = new PutOperation<K, V>(key, oldValue, value);
+ getDelta().addOperation(op);
+ return oldValue;
+ }
+
+ public V remove(Object key) {
+ V oldValue = delegate.remove(key);
+ RemoveOperation<K, V> op = new RemoveOperation<K, V>((K)key, oldValue);
+ getDelta().addOperation(op);
+ return oldValue;
+ }
+
+ public void putAll(Map<? extends K, ? extends V> t) {
+ // this is crappy - need to do this more efficiently!
+ for (Entry<? extends K, ? extends V> e : t.entrySet()) put(e.getKey(), e.getValue());
+ }
+
+ public void clear() {
+ FastCopyHashMap<K, V> originalEntries = (FastCopyHashMap<K, V>) delegate.clone();
+ ClearOperation<K, V> op = new ClearOperation<K, V>(originalEntries);
+ if (delta!= null ) delta.addOperation(op);
+ delegate.clear();
+ }
+
+ public AtomicMap getProxy(Cache cache, Object mapKey,
+ BatchContainer batchContainer, InvocationContextContainer icc) {
+ // construct the proxy lazily
+ if (proxy == null) // DCL is OK here since proxy is volatile (and we live in a post-JDK 5 world)
+ {
+ synchronized (this) {
+ if (proxy == null)
+ proxy = new AtomicHashMapProxy(cache, mapKey, batchContainer, icc);
+ }
+ }
+ return proxy;
+ }
+
+ public Delta delta() {
+ Delta toReturn = delta == null ? NullDelta.INSTANCE : delta;
+ delta = null; // reset
+ return toReturn;
+ }
+
+ public AtomicHashMap copyForWrite() {
+ try {
+ AtomicHashMap clone = (AtomicHashMap) super.clone();
+ clone.delegate = (FastCopyHashMap) delegate.clone();
+ clone.proxy = proxy;
+ return clone;
+ }
+ catch (CloneNotSupportedException e) {
+ // should never happen!!
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "AtomicHashMap{" +
+ "delegate=" + delegate +
+ '}';
+ }
+
+ /**
+ * Initializes the delta instance to start recording changes.
+ */
+ public void initForWriting() {
+ delta = new AtomicHashMapDelta();
+ }
+
+ private AtomicHashMapDelta getDelta() {
+ if (delta == null) delta = new AtomicHashMapDelta();
+ return delta;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMap.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapDelta.java (from rev 208, trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapDelta.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapDelta.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.atomic.atomichashmap;
+
+import org.infinispan.atomic.Delta;
+import org.infinispan.atomic.DeltaAware;
+import org.infinispan.atomic.Operation;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Changes that have occured on an AtomicHashMap
+ *
+ * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
+ * @since 4.0
+ */
+public class AtomicHashMapDelta implements Delta {
+ private static final Log log = LogFactory.getLog(AtomicHashMapDelta.class);
+ private static final boolean trace = log.isTraceEnabled();
+
+ private List<Operation> changelog;
+
+ public DeltaAware merge(DeltaAware d) {
+ AtomicHashMap other;
+ if (d != null && (d instanceof AtomicHashMap))
+ other = (AtomicHashMap) d;
+ else
+ other = new AtomicHashMap();
+
+ for (Operation o : changelog) o.replay(other.delegate);
+ other.commit();
+ return other;
+ }
+
+ public void addOperation(Operation o) {
+ if (changelog == null) {
+ // lazy init
+ changelog = new LinkedList<Operation>();
+ }
+ changelog.add(o);
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ if (trace) log.trace("Serializing changelog " + changelog);
+ out.writeObject(changelog);
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ changelog = (List<Operation>) in.readObject();
+ if (trace) log.trace("Deserialized changelog " + changelog);
+ }
+
+ @Override
+ public String toString() {
+ return "AtomicHashMapDelta{" +
+ "changelog=" + changelog +
+ '}';
+ }
+
+ public int getChangeLogSize() {
+ return changelog == null ? 0 : changelog.size();
+ }
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapDelta.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapProxy.java (from rev 208, trunk/core/src/main/java/org/infinispan/atomic/AtomicHashMapProxy.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapProxy.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapProxy.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,176 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.atomic.atomichashmap;
+
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.batch.AutoBatchSupport;
+import org.infinispan.batch.BatchContainer;
+import org.infinispan.context.Flag;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A layer of indirection around an {@link AtomicHashMap} to provide reader consistency
+ *
+ * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
+ * @since 4.0
+ */
+public class AtomicHashMapProxy<K, V> extends AutoBatchSupport implements AtomicMap<K, V> {
+ private static final Log log = LogFactory.getLog(AtomicHashMapProxy.class);
+ private static final boolean trace = log.isTraceEnabled();
+ Object deltaMapKey;
+ Cache cache;
+ InvocationContextContainer icc;
+
+ public AtomicHashMapProxy(Cache cache, Object deltaMapKey, BatchContainer batchContainer, InvocationContextContainer icc) {
+ this.cache = cache;
+ this.deltaMapKey = deltaMapKey;
+ this.batchContainer = batchContainer;
+ this.icc = icc;
+ }
+
+ // internal helper, reduces lots of casts.
+ private AtomicHashMap<K, V> getDeltaMapForRead() {
+ return (AtomicHashMap<K, V>) cache.get(deltaMapKey);
+ }
+
+ private AtomicHashMap<K, V> getDeltaMapForWrite(InvocationContext ctx) {
+ if (ctx.hasLockedKey(deltaMapKey)) {
+ return (AtomicHashMap<K, V>) cache.get(deltaMapKey);
+ } else {
+ // acquire WL
+ boolean suppressLocks = ctx.hasFlag(Flag.SKIP_LOCKING);
+ if (!suppressLocks) ctx.setFlags(Flag.FORCE_WRITE_LOCK);
+
+ if (trace) {
+ if (suppressLocks)
+ log.trace("Skip locking flag used. Skipping locking.");
+ else
+ log.trace("Forcing write lock even for reads");
+ }
+
+ AtomicHashMap map = getDeltaMapForRead();
+ // copy for write
+ AtomicHashMap copy = map == null ? new AtomicHashMap() : map.copyForWrite();
+ copy.initForWriting();
+ // reinstate the flag
+ if (suppressLocks) ctx.setFlags(Flag.SKIP_LOCKING);
+ cache.put(deltaMapKey, copy);
+ return copy;
+ }
+ }
+
+ // readers
+
+ public Set<K> keySet() {
+ return getDeltaMapForRead().keySet();
+ }
+
+ public Collection<V> values() {
+ return getDeltaMapForRead().values();
+ }
+
+ public Set<Entry<K, V>> entrySet() {
+ return getDeltaMapForRead().entrySet();
+ }
+
+ public int size() {
+ return getDeltaMapForRead().size();
+ }
+
+ public boolean isEmpty() {
+ return getDeltaMapForRead().isEmpty();
+ }
+
+ public boolean containsKey(Object key) {
+ return getDeltaMapForRead().containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return getDeltaMapForRead().containsValue(value);
+ }
+
+ public V get(Object key) {
+ return getDeltaMapForRead().get(key);
+ }
+
+ // writers
+
+ public V put(K key, V value) {
+ try {
+ startAtomic();
+ InvocationContext ctx = icc.getLocalInvocationContext(true);
+ AtomicHashMap<K, V> deltaMapForWrite = getDeltaMapForWrite(ctx);
+ return deltaMapForWrite.put(key, value);
+ }
+ finally {
+ endAtomic();
+ }
+ }
+
+ public V remove(Object key) {
+ try {
+ startAtomic();
+ InvocationContext ic = icc.getLocalInvocationContext(true);
+ return getDeltaMapForWrite(ic).remove(key);
+ }
+ finally {
+ endAtomic();
+ }
+ }
+
+ public void putAll(Map<? extends K, ? extends V> m) {
+ try {
+ startAtomic();
+ InvocationContext ic = icc.getLocalInvocationContext(true);
+ getDeltaMapForWrite(ic).putAll(m);
+ }
+ finally {
+ endAtomic();
+ }
+ }
+
+ public void clear() {
+ try {
+ startAtomic();
+ InvocationContext ic = icc.getLocalInvocationContext(true);
+ getDeltaMapForWrite(ic).clear();
+ }
+ finally {
+ endAtomic();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "AtomicHashMapProxy{" +
+ "deltaMapKey=" + deltaMapKey +
+ '}';
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/atomic/atomichashmap/AtomicHashMapProxy.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/atomic/operations/ClearOperation.java (from rev 208, trunk/core/src/main/java/org/infinispan/atomic/ClearOperation.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/operations/ClearOperation.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/atomic/operations/ClearOperation.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.atomic.operations;
+
+import org.infinispan.util.FastCopyHashMap;
+import org.infinispan.atomic.Operation;
+
+import java.util.Map;
+
+
+public class ClearOperation<K, V> extends Operation<K, V> {
+ FastCopyHashMap<K, V> originalEntries;
+
+ public ClearOperation() {
+ }
+
+ public ClearOperation(FastCopyHashMap<K, V> originalEntries) {
+ this.originalEntries = originalEntries;
+ }
+
+ public void rollback(Map<K, V> delegate) {
+ if (!originalEntries.isEmpty()) delegate.putAll(originalEntries);
+ }
+
+ public void replay(Map<K, V> delegate) {
+ delegate.clear();
+ }
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/atomic/operations/ClearOperation.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/atomic/operations/PutOperation.java (from rev 208, trunk/core/src/main/java/org/infinispan/atomic/PutOperation.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/operations/PutOperation.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/atomic/operations/PutOperation.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,69 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.atomic.operations;
+
+import org.infinispan.atomic.Operation;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+
+
+public class PutOperation<K, V> extends Operation<K, V> {
+ private K key;
+ private V oldValue;
+ private V newValue;
+
+ public PutOperation() {
+ }
+
+ public PutOperation(K key, V oldValue, V newValue) {
+ this.key = key;
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ }
+
+ public void rollback(Map<K, V> delegate) {
+ if (oldValue == null)
+ delegate.remove(key);
+ else
+ delegate.put(key, oldValue);
+ }
+
+ public void replay(Map<K, V> delegate) {
+ delegate.put(key, newValue);
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ // don't bother writing out the old value since it will never be rolled back
+ out.writeObject(key);
+ out.writeObject(newValue);
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ key = (K) in.readObject();
+ newValue = (V) in.readObject();
+ }
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/atomic/operations/PutOperation.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/atomic/operations/RemoveOperation.java (from rev 208, trunk/core/src/main/java/org/infinispan/atomic/RemoveOperation.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/atomic/operations/RemoveOperation.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/atomic/operations/RemoveOperation.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.atomic.operations;
+
+import org.infinispan.atomic.Operation;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+
+
+public class RemoveOperation<K, V> extends Operation<K, V> {
+ private K key;
+ private V oldValue;
+
+ public RemoveOperation() {
+ }
+
+ public RemoveOperation(K key, V oldValue) {
+ this.key = key;
+ this.oldValue = oldValue;
+ }
+
+ public void rollback(Map<K, V> delegate) {
+ if (oldValue != null) delegate.put(key, oldValue);
+ }
+
+ public void replay(Map<K, V> delegate) {
+ delegate.remove(key);
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(key);
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ key = (K) in.readObject();
+ }
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/atomic/operations/RemoveOperation.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/core/src/main/java/org/infinispan/batch/BatchContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/batch/BatchContainer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/batch/BatchContainer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -36,7 +36,7 @@
*/
public class BatchContainer {
TransactionManager transactionManager;
- private ThreadLocal<BatchDetails> batchDetails = new ThreadLocal<BatchDetails>() {
+ private ThreadLocal<BatchDetails> batchDetailsTl = new ThreadLocal<BatchDetails>() {
@Override
protected BatchDetails initialValue() {
return new BatchDetails();
@@ -59,11 +59,11 @@
}
public boolean startBatch(boolean autoBatch) throws CacheException {
- BatchDetails bd = batchDetails.get();
+ BatchDetails bd = batchDetailsTl.get();
try {
if (transactionManager.getTransaction() == null && bd.tx == null) {
transactionManager.begin();
- bd.invocationCount = 1;
+ bd.nestedInvocationCount = 1;
bd.suspendTxAfterInvocation = !autoBatch;
// do not suspend if this is from an AutoBatch!
@@ -74,7 +74,7 @@
return true;
} else {
- bd.invocationCount++;
+ bd.nestedInvocationCount++;
return false;
}
}
@@ -82,7 +82,7 @@
throw new CacheException("Unable to start batch", e);
}
finally {
- batchDetails.set(bd);
+ batchDetailsTl.set(bd);
}
}
@@ -91,10 +91,10 @@
}
public void endBatch(boolean autoBatch, boolean success) {
- BatchDetails bd = batchDetails.get();
+ BatchDetails bd = batchDetailsTl.get();
if (bd.tx == null) return;
- if (autoBatch) bd.invocationCount--;
- if (!autoBatch || bd.invocationCount == 0) {
+ if (autoBatch) bd.nestedInvocationCount--;
+ if (!autoBatch || bd.nestedInvocationCount == 0) {
Transaction existingTx = null;
try {
existingTx = transactionManager.getTransaction();
@@ -111,7 +111,7 @@
throw new CacheException("Unable to end batch", e);
}
finally {
- batchDetails.remove();
+ batchDetailsTl.remove();
try {
if (!autoBatch && existingTx != null) transactionManager.resume(existingTx);
}
@@ -120,20 +120,20 @@
}
}
} else {
- batchDetails.set(bd);
+ batchDetailsTl.set(bd);
}
}
public Transaction getBatchTransaction() {
- return batchDetails.get().tx;
+ return batchDetailsTl.get().tx;
}
public boolean isSuspendTxAfterInvocation() {
- return batchDetails.get().suspendTxAfterInvocation;
+ return batchDetailsTl.get().suspendTxAfterInvocation;
}
private static class BatchDetails {
- int invocationCount;
+ int nestedInvocationCount;
boolean suspendTxAfterInvocation;
Transaction tx;
}
Modified: trunk/core/src/main/java/org/infinispan/commands/AbstractVisitor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/AbstractVisitor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/AbstractVisitor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -34,6 +34,7 @@
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
import java.util.Collection;
@@ -83,15 +84,15 @@
// tx commands
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
return handleDefault(ctx, command);
}
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
return handleDefault(ctx, command);
}
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
return handleDefault(ctx, command);
}
Modified: trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -37,10 +37,10 @@
import org.infinispan.commands.write.PutMapCommand;
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
+import org.infinispan.commands.write.WriteCommand;
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import java.util.Collection;
import java.util.List;
@@ -73,7 +73,7 @@
EvictCommand buildEvictCommand(Object key);
- PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List modifications, Address localAddress, boolean onePhaseCommit);
+ PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, boolean onePhaseCommit);
CommitCommand buildCommitCommand(GlobalTransaction gtx);
Modified: trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -39,15 +39,16 @@
import org.infinispan.commands.write.PutMapCommand;
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
+import org.infinispan.commands.write.WriteCommand;
import org.infinispan.container.DataContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.distribution.DistributionManager;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.interceptors.InterceptorChain;
import org.infinispan.loaders.CacheLoaderManager;
import org.infinispan.notifications.cachelistener.CacheNotifier;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import java.util.Collection;
import java.util.List;
@@ -68,17 +69,19 @@
SizeCommand cachedSizeCommand;
private InterceptorChain interceptorChain;
private DistributionManager distributionManager;
+ private InvocationContextContainer icc;
@Inject
public void setupDependencies(DataContainer container, CacheNotifier notifier, Cache cache,
InterceptorChain interceptorChain, CacheLoaderManager clManager,
- DistributionManager distributionManager) {
+ DistributionManager distributionManager, InvocationContextContainer icc) {
this.dataContainer = container;
this.notifier = notifier;
this.cache = cache;
this.interceptorChain = interceptorChain;
this.cacheLoaderManager = clManager;
this.distributionManager = distributionManager;
+ this.icc = icc;
}
@Start(priority = 1)
@@ -131,16 +134,22 @@
return command;
}
- public PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List modifications, Address localAddress, boolean onePhaseCommit) {
- return new PrepareCommand(gtx, modifications, localAddress, onePhaseCommit);
+ public PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, boolean onePhaseCommit) {
+ PrepareCommand command = new PrepareCommand(gtx, modifications, onePhaseCommit);
+ command.setCacheName(cacheName);
+ return command;
}
public CommitCommand buildCommitCommand(GlobalTransaction gtx) {
- return new CommitCommand(gtx);
+ CommitCommand commitCommand = new CommitCommand(gtx);
+ commitCommand.setCacheName(cacheName);
+ return commitCommand;
}
public RollbackCommand buildRollbackCommand(GlobalTransaction gtx) {
- return new RollbackCommand(gtx);
+ RollbackCommand rollbackCommand = new RollbackCommand(gtx);
+ rollbackCommand.setCacheName(cacheName);
+ return rollbackCommand;
}
public MultipleRpcCommand buildReplicateCommand(List<ReplicableCommand> toReplicate) {
@@ -173,7 +182,7 @@
break;
case MultipleRpcCommand.COMMAND_ID:
MultipleRpcCommand rc = (MultipleRpcCommand) c;
- rc.setInterceptorChain(interceptorChain);
+ rc.init(interceptorChain, icc);
if (rc.getCommands() != null)
for (ReplicableCommand nested : rc.getCommands()) {
initializeReplicableCommand(nested);
@@ -181,7 +190,7 @@
break;
case SingleRpcCommand.COMMAND_ID:
SingleRpcCommand src = (SingleRpcCommand) c;
- src.setInterceptorChain(interceptorChain);
+ src.init(interceptorChain, icc);
if (src.getCommand() != null)
initializeReplicableCommand(src.getCommand());
@@ -196,16 +205,26 @@
break;
case PrepareCommand.COMMAND_ID:
PrepareCommand pc = (PrepareCommand) c;
+ pc.init(interceptorChain, icc);
+ pc.initialize(notifier);
if (pc.getModifications() != null)
for (ReplicableCommand nested : pc.getModifications()) initializeReplicableCommand(nested);
break;
+ case CommitCommand.COMMAND_ID:
+ CommitCommand commitCommand = (CommitCommand) c;
+ commitCommand.init(interceptorChain, icc);
+ break;
+ case RollbackCommand.COMMAND_ID:
+ RollbackCommand rollbackCommand = (RollbackCommand) c;
+ rollbackCommand.init(interceptorChain, icc);
+ break;
case ClearCommand.COMMAND_ID:
ClearCommand cc = (ClearCommand) c;
cc.init(notifier);
break;
case ClusteredGetCommand.COMMAND_ID:
ClusteredGetCommand clusteredGetCommand = (ClusteredGetCommand) c;
- clusteredGetCommand.initialize(dataContainer, cacheLoaderManager);
+ clusteredGetCommand.initialize(dataContainer, cacheLoaderManager, icc);
break;
}
}
Modified: trunk/core/src/main/java/org/infinispan/commands/RemoteCommandFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/RemoteCommandFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/RemoteCommandFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -19,7 +19,7 @@
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
/**
* Specifically used to create un-initialized {@link org.infinispan.commands.ReplicableCommand}s from a byte stream.
Modified: trunk/core/src/main/java/org/infinispan/commands/ReplicableCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/ReplicableCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/ReplicableCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -25,7 +25,7 @@
/**
* The core of the command-based cache framework. Commands correspond to specific areas of functionality in the cache,
- * and can be replicated using the {@link org.infinispan.remoting.RpcManager}
+ * and can be replicated using the {@link org.infinispan.remoting.rpc.RpcManager}
*
* @author Mircea.Markus at jboss.com
* @author Manik Surtani
Deleted: trunk/core/src/main/java/org/infinispan/commands/TransactionBoundaryCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/TransactionBoundaryCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/TransactionBoundaryCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,36 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.commands;
-
-import org.infinispan.transaction.GlobalTransaction;
-
-/**
- * // TODO: MANIK: Document this
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 4.0
- */
-public interface TransactionBoundaryCommand extends VisitableCommand {
- GlobalTransaction getGlobalTransaction();
-
- void setGlobalTransaction(GlobalTransaction gtx);
-}
Modified: trunk/core/src/main/java/org/infinispan/commands/Visitor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/Visitor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/Visitor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -34,7 +34,13 @@
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+
public interface Visitor {
// write commands
@@ -58,11 +64,11 @@
// tx commands
- Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable;
+ Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable;
- Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable;
+ Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable;
- Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable;
+ Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable;
Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand invalidateCommand) throws Throwable;
Modified: trunk/core/src/main/java/org/infinispan/commands/control/StateTransferControlCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/control/StateTransferControlCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/control/StateTransferControlCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -2,7 +2,7 @@
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.context.InvocationContext;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
/**
* A command that informs caches participating in a state transfer of the various stages in the state transfer process.
Modified: trunk/core/src/main/java/org/infinispan/commands/remote/BaseRpcCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/remote/BaseRpcCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/remote/BaseRpcCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -2,10 +2,11 @@
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.commands.VisitableCommand;
-import org.infinispan.context.InvocationContext;
import org.infinispan.interceptors.InterceptorChain;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.container.InvocationContextContainer;
/**
* Base class for RPC commands.
@@ -15,6 +16,7 @@
public abstract class BaseRpcCommand implements CacheRpcCommand {
protected InterceptorChain interceptorChain;
+ protected InvocationContextContainer icc;
protected String cacheName;
private static final Log log = LogFactory.getLog(BaseRpcCommand.class);
@@ -31,38 +33,19 @@
return cacheName;
}
- public void setInterceptorChain(InterceptorChain interceptorChain) {
+ public void init(InterceptorChain interceptorChain, InvocationContextContainer icc) {
this.interceptorChain = interceptorChain;
+ this.icc = icc;
}
-
- protected final Object processCommand(InvocationContext ctx, ReplicableCommand cacheCommand) throws Throwable {
- Object result;
- try {
- if (trace) log.trace("Invoking command " + cacheCommand + ", with originLocal flag set to false.");
- ctx.setOriginLocal(false);
- if (cacheCommand instanceof VisitableCommand) {
- Object retVal = interceptorChain.invokeRemote((VisitableCommand) cacheCommand);
- // we only need to return values for a set of remote calls; not every call.
- result = null;
- } else {
- throw new RuntimeException("Do we still need to deal with non-visitable commands? (" + cacheCommand.getClass().getName() + ")");
-// result = cacheCommand.perform(null);
- }
+ protected final Object processVisitableCommand(ReplicableCommand cacheCommand) throws Throwable {
+ if (cacheCommand instanceof VisitableCommand) {
+ InvocationContext ctx = icc.getRemoteNonTxInvocationContext();
+ if (trace) log.trace("Invoking command " + cacheCommand + ", with originLocal flag set to " + ctx.isOriginLocal() + ".");
+ return interceptorChain.invoke(ctx, (VisitableCommand) cacheCommand);
+ // we only need to return values for a set of remote calls; not every call.
+ } else {
+ throw new RuntimeException("Do we still need to deal with non-visitable commands? (" + cacheCommand.getClass().getName() + ")");
}
- catch (Throwable ex) {
- // TODO deal with PFER
-// if (!(cacheCommand instanceof PutForExternalReadCommand))
-// {
- throw ex;
-// }
-// else
-// {
-// if (trace)
-// log.trace("Caught an exception, but since this is a putForExternalRead() call, suppressing the exception. Exception is:", ex);
-// result = null;
-// }
- }
- return result;
}
}
Modified: trunk/core/src/main/java/org/infinispan/commands/remote/CacheRpcCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/remote/CacheRpcCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/remote/CacheRpcCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -3,7 +3,7 @@
import org.infinispan.commands.ReplicableCommand;
/**
- * The {@link org.infinispan.remoting.RpcManager} only replicates commands wrapped in a {@link CacheRpcCommand}.
+ * The {@link org.infinispan.remoting.rpc.RpcManager} only replicates commands wrapped in a {@link CacheRpcCommand}.
*
* @author Manik Surtani
* @author Mircea.Markus at jboss.com
Modified: trunk/core/src/main/java/org/infinispan/commands/remote/ClusteredGetCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/remote/ClusteredGetCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/remote/ClusteredGetCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -26,12 +26,13 @@
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.loaders.CacheLoaderManager;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
/**
- * Issues a clustered get call, for use primarily by the {@link org.infinispan.loaders.cluster.ClusterCacheLoader}. This
+ * Issues a clustered get call, for use primarily by the {@link org.infinispan.loader.cluster.ClusterCacheLoader}. This
* is not a {@link org.infinispan.commands.VisitableCommand} and hence not passed up the {@link
* org.infinispan.interceptors.base.CommandInterceptor} chain.
* <p/>
@@ -41,7 +42,7 @@
*/
public class ClusteredGetCommand implements CacheRpcCommand {
- public static final byte COMMAND_ID = 3;
+ public static final byte COMMAND_ID = 22;
private static final Log log = LogFactory.getLog(ClusteredGetCommand.class);
private static final boolean trace = log.isTraceEnabled();
@@ -50,6 +51,7 @@
private DataContainer dataContainer;
private CacheLoaderManager cacheLoaderManager;
+ private InvocationContextContainer icc;
public ClusteredGetCommand() {
}
@@ -59,9 +61,10 @@
this.cacheName = cacheName;
}
- public void initialize(DataContainer dataContainer, CacheLoaderManager clManager) {
+ public void initialize(DataContainer dataContainer, CacheLoaderManager clManager, InvocationContextContainer icc) {
this.dataContainer = dataContainer;
this.cacheLoaderManager = clManager;
+ this.icc = icc;
}
/**
@@ -76,10 +79,14 @@
if (trace) log.trace("Found InternalCacheEntry {0} for key {1}", cacheEntry, key);
if (cacheEntry == null) {
if (trace) log.trace("Checking in cache loader");
- context.setOriginLocal(false); //to make sure that if there is an ClusteredCl, this won't initiate a remote
+ // hack -> the call is here to make sure that the current thread is associated with
+ // the remote InvocationCOntext in order to make sure that ClusterCL won't trigger a recurring cluster get
+ // which might result in infinite loops
+ icc.getRemoteNonTxInvocationContext();
// lookup
- if (cacheLoaderManager != null && cacheLoaderManager.getCacheLoader() != null)
+ if (cacheLoaderManager != null && cacheLoaderManager.getCacheLoader() != null) {
cacheEntry = cacheLoaderManager.getCacheLoader().load(key);
+ }
}
return cacheEntry;
} else {
Modified: trunk/core/src/main/java/org/infinispan/commands/remote/MultipleRpcCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/remote/MultipleRpcCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/remote/MultipleRpcCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,6 +23,7 @@
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.tx.TransactionBoundaryCommand;
import org.infinispan.context.InvocationContext;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -62,7 +63,13 @@
*/
public Object perform(InvocationContext ctx) throws Throwable {
if (trace) log.trace("Executing remotely originated commands: " + commands.length);
- for (ReplicableCommand command : commands) processCommand(ctx, command);
+ for (ReplicableCommand command : commands) {
+ if (command instanceof TransactionBoundaryCommand) {
+ command.perform(null);
+ } else {
+ processVisitableCommand(command);
+ }
+ }
return null;
}
Modified: trunk/core/src/main/java/org/infinispan/commands/remote/SingleRpcCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/remote/SingleRpcCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/remote/SingleRpcCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -41,7 +41,7 @@
}
public Object perform(InvocationContext ctx) throws Throwable {
- return processCommand(ctx, command);
+ return processVisitableCommand(command);
}
@Override
Modified: trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,37 +21,68 @@
*/
package org.infinispan.commands.tx;
-import org.infinispan.commands.TransactionBoundaryCommand;
import org.infinispan.context.InvocationContext;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.context.impl.RemoteTxInvocationContext;
+import org.infinispan.interceptors.InterceptorChain;
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
- * An abstract transaction boundary command that holds a reference to a {@link GlobalTransaction}
+ * An abstract transaction boundary command that holds a reference to a {@link org.infinispan.transaction.xa.GlobalTransaction}
*
* @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @author Mircea.Markus at jboss.com
* @since 4.0
*/
public abstract class AbstractTransactionBoundaryCommand implements TransactionBoundaryCommand {
- GlobalTransaction gtx;
+ private static Log log = LogFactory.getLog(AbstractTransactionBoundaryCommand.class);
+
+ protected GlobalTransaction globalTx;
+ protected String cacheName;
+ protected InterceptorChain invoker;
+ protected InvocationContextContainer icc;
+
+ public void init(InterceptorChain chain, InvocationContextContainer icc) {
+ this.invoker = chain;
+ this.icc = icc;
+ }
+
+ public String getCacheName() {
+ return cacheName;
+ }
+
+ public void setCacheName(String cacheName) {
+ this.cacheName = cacheName;
+ }
+
public GlobalTransaction getGlobalTransaction() {
- return gtx;
+ return globalTx;
}
- public void setGlobalTransaction(GlobalTransaction gtx) {
- this.gtx = gtx;
+ public void GlobalTransaction(GlobalTransaction gtx) {
+ this.globalTx = gtx;
}
public Object perform(InvocationContext ctx) throws Throwable {
- return null;
+ if (ctx != null) throw new IllegalStateException("Expected null context!");
+ RemoteTxInvocationContext ctxt = icc.getRemoteTxInvocationContext(getGlobalTransaction(), false);
+ if (ctxt == null) {
+ if (log.isInfoEnabled()) log.info("Not found RemoteTxInvocationContext for tx: " + getGlobalTransaction());
+ return null;
+ }
+ return invoker.invoke(ctxt, this);
}
public Object[] getParameters() {
- return new Object[]{gtx};
+ return new Object[]{globalTx, cacheName};
}
public void setParameters(int commandId, Object[] args) {
- gtx = (GlobalTransaction) args[0];
+ globalTx = (GlobalTransaction) args[0];
+ cacheName = (String) args[1];
}
public boolean equals(Object o) {
@@ -59,13 +90,19 @@
if (o == null || getClass() != o.getClass()) return false;
AbstractTransactionBoundaryCommand that = (AbstractTransactionBoundaryCommand) o;
-
- if (gtx != null ? !gtx.equals(that.gtx) : that.gtx != null) return false;
-
- return true;
+ return this.globalTx.equals(that.globalTx);
}
public int hashCode() {
- return (gtx != null ? gtx.hashCode() : 0);
+ return globalTx.hashCode();
}
+
+ @Override
+ public String toString() {
+ return "AbstractTransactionBoundaryCommand{" +
+ "globalTx=" + globalTx +
+ ", cacheName='" + cacheName + '\'' +
+ ", invoker=" + invoker +
+ '}';
+ }
}
Modified: trunk/core/src/main/java/org/infinispan/commands/tx/CommitCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/CommitCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/CommitCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,7 +23,8 @@
import org.infinispan.commands.Visitor;
import org.infinispan.context.InvocationContext;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.context.impl.TxInvocationContext;
+import org.infinispan.transaction.xa.GlobalTransaction;
/**
* // TODO: MANIK: Document this
@@ -35,14 +36,14 @@
public static final byte COMMAND_ID = 14;
public CommitCommand(GlobalTransaction gtx) {
- this.gtx = gtx;
+ this.globalTx = gtx;
}
public CommitCommand() {
}
public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable {
- return visitor.visitCommitCommand(ctx, this);
+ return visitor.visitCommitCommand((TxInvocationContext)ctx, this);
}
public byte getCommandId() {
@@ -51,7 +52,7 @@
public String toString() {
return "CommitCommand {" +
- "gtx=" + gtx +
+ "gtx=" + globalTx +
'}';
}
}
Modified: trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -25,74 +25,64 @@
import org.infinispan.commands.Visitor;
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.context.InvocationContext;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.context.impl.RemoteTxInvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
+import org.infinispan.notifications.cachelistener.CacheNotifier;
+import org.infinispan.transaction.xa.GlobalTransaction;
import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* // TODO: MANIK: Document this
*
* @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @author Mircea.Markus at jboss.com
* @since 4.0
*/
public class PrepareCommand extends AbstractTransactionBoundaryCommand {
+
public static final byte COMMAND_ID = 12;
protected WriteCommand[] modifications;
- protected Address localAddress;
protected boolean onePhaseCommit;
+ protected CacheNotifier notifier;
- public PrepareCommand(GlobalTransaction gtx, Address localAddress, boolean onePhaseCommit, WriteCommand... modifications) {
- this.gtx = gtx;
+ public void initialize(CacheNotifier notifier) {
+ this.notifier = notifier;
+ }
+
+ public PrepareCommand(GlobalTransaction gtx, boolean onePhaseCommit, WriteCommand... modifications) {
+ this.globalTx = gtx;
this.modifications = modifications;
- this.localAddress = localAddress;
this.onePhaseCommit = onePhaseCommit;
}
- public PrepareCommand(GlobalTransaction gtx, List<WriteCommand> commands, Address localAddress, boolean onePhaseCommit) {
- this.gtx = gtx;
+ public PrepareCommand(GlobalTransaction gtx, List<WriteCommand> commands, boolean onePhaseCommit) {
+ this.globalTx = gtx;
this.modifications = commands == null || commands.size() == 0 ? null : commands.toArray(new WriteCommand[commands.size()]);
- this.localAddress = localAddress;
this.onePhaseCommit = onePhaseCommit;
}
- public void removeModifications(Collection<WriteCommand> modificationsToRemove) {
- if (modifications != null && modificationsToRemove != null && modificationsToRemove.size() > 0) {
- // defensive copy
- Set<WriteCommand> toRemove = new HashSet<WriteCommand>(modificationsToRemove);
- WriteCommand[] newMods = new WriteCommand[modifications.length - modificationsToRemove.size()];
- int i = 0;
- for (WriteCommand c : modifications) {
- if (toRemove.contains(c)) {
- toRemove.remove(c);
- } else {
- newMods[i++] = c;
- }
- }
- modifications = newMods;
- }
+ public PrepareCommand() {
}
- public PrepareCommand() {
+ public final Object perform(InvocationContext ignored) throws Throwable {
+ if (ignored != null) throw new IllegalStateException("Expected null context!");
+ RemoteTxInvocationContext ctx = icc.getRemoteTxInvocationContext(getGlobalTransaction(), true);
+ notifier.notifyTransactionRegistered(ctx.getClusterTransactionId(), ctx);
+ ctx.initialize(modifications, globalTx);
+ return invoker.invoke(ctx, this);
}
public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable {
- return visitor.visitPrepareCommand(ctx, this);
+ return visitor.visitPrepareCommand((TxInvocationContext) ctx, this);
}
public WriteCommand[] getModifications() {
return modifications;
}
- public Address getLocalAddress() {
- return localAddress;
- }
-
public boolean isOnePhaseCommit() {
return onePhaseCommit;
}
@@ -113,8 +103,8 @@
public Object[] getParameters() {
int numMods = modifications == null ? 0 : modifications.length;
Object[] retval = new Object[numMods + 4];
- retval[0] = gtx;
- retval[1] = localAddress;
+ retval[0] = globalTx;
+ retval[1] = cacheName;
retval[2] = onePhaseCommit;
retval[3] = numMods;
if (numMods > 0) System.arraycopy(modifications, 0, retval, 4, numMods);
@@ -124,8 +114,8 @@
@Override
@SuppressWarnings("unchecked")
public void setParameters(int commandId, Object[] args) {
- gtx = (GlobalTransaction) args[0];
- localAddress = (Address) args[1];
+ globalTx = (GlobalTransaction) args[0];
+ cacheName = (String) args[1];
onePhaseCommit = (Boolean) args[2];
int numMods = (Integer) args[3];
if (numMods > 0) {
@@ -134,35 +124,9 @@
}
}
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- if (!super.equals(o)) return false;
-
- PrepareCommand that = (PrepareCommand) o;
-
- if (onePhaseCommit != that.onePhaseCommit) return false;
- if (localAddress != null ? !localAddress.equals(that.localAddress) : that.localAddress != null) return false;
- if (modifications != null ? !Arrays.equals(modifications, that.modifications) : that.modifications != null)
- return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + (modifications != null ? modifications.hashCode() : 0);
- result = 31 * result + (localAddress != null ? localAddress.hashCode() : 0);
- result = 31 * result + (onePhaseCommit ? 1 : 0);
- return result;
- }
-
public PrepareCommand copy() {
PrepareCommand copy = new PrepareCommand();
- copy.gtx = gtx;
- copy.localAddress = localAddress;
+ copy.globalTx = globalTx;
copy.modifications = modifications == null ? null : modifications.clone();
copy.onePhaseCommit = onePhaseCommit;
return copy;
@@ -171,11 +135,9 @@
@Override
public String toString() {
return "PrepareCommand{" +
- "globalTransaction=" + gtx +
- ", modifications=" + Arrays.toString(modifications) +
- ", localAddress=" + localAddress +
+ "modifications=" + (modifications == null ? null : Arrays.asList(modifications)) +
", onePhaseCommit=" + onePhaseCommit +
- '}';
+ "} " + super.toString();
}
public boolean containsModificationType(Class<? extends ReplicableCommand> replicableCommandClass) {
@@ -186,4 +148,8 @@
}
return false;
}
+
+ public boolean hasModifications() {
+ return modifications != null && modifications.length > 0;
+ }
}
Modified: trunk/core/src/main/java/org/infinispan/commands/tx/RollbackCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/RollbackCommand.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/RollbackCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,7 +23,8 @@
import org.infinispan.commands.Visitor;
import org.infinispan.context.InvocationContext;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.context.impl.TxInvocationContext;
+import org.infinispan.transaction.xa.GlobalTransaction;
/**
* // TODO: MANIK: Document this
@@ -35,14 +36,14 @@
public static final byte COMMAND_ID = 13;
public RollbackCommand(GlobalTransaction globalTransaction) {
- this.gtx = globalTransaction;
+ this.globalTx = globalTransaction;
}
public RollbackCommand() {
}
public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable {
- return visitor.visitRollbackCommand(ctx, this);
+ return visitor.visitRollbackCommand((TxInvocationContext)ctx, this);
}
public byte getCommandId() {
@@ -51,7 +52,7 @@
public String toString() {
return "RollbackCommand{" +
- "gtx=" + gtx +
+ "gtx=" + globalTx +
'}';
}
}
Copied: trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java (from rev 204, trunk/core/src/main/java/org/infinispan/commands/TransactionBoundaryCommand.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.commands.tx;
+
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.commands.remote.CacheRpcCommand;
+import org.infinispan.commands.VisitableCommand;
+
+/**
+ * // TODO: MANIK: Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 4.0
+ */
+public interface TransactionBoundaryCommand extends VisitableCommand, CacheRpcCommand {
+
+ GlobalTransaction getGlobalTransaction();
+
+ void GlobalTransaction(GlobalTransaction gtx);
+}
Property changes on: trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/core/src/main/java/org/infinispan/config/Configuration.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/Configuration.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/config/Configuration.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -139,6 +139,10 @@
return this == DIST_SYNC || this == DIST_ASYNC;
}
+ public boolean isReplicated() {
+ return this == REPL_SYNC || this == REPL_ASYNC;
+ }
+
public CacheMode toSync() {
switch (this) {
case REPL_ASYNC:
@@ -700,4 +704,8 @@
if (cacheMode.isDistributed() && fetchInMemoryState)
throw new ConfigurationException("Cache cannot use DISTRIBUTION mode and have fetchInMemoryState set to true");
}
+
+ public boolean isOnePhaseCommit() {
+ return !getCacheMode().isSynchronous();
+ }
}
Modified: trunk/core/src/main/java/org/infinispan/config/RuntimeConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/RuntimeConfig.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/config/RuntimeConfig.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,7 +21,7 @@
*/
package org.infinispan.config;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.util.Util;
import javax.transaction.TransactionManager;
Modified: trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -9,7 +9,7 @@
import org.infinispan.config.parsing.element.CustomInterceptorsElementParser;
import org.infinispan.config.parsing.element.LoadersElementParser;
import org.infinispan.eviction.EvictionStrategy;
-import org.infinispan.transaction.GenericTransactionManagerLookup;
+import org.infinispan.transaction.lookup.GenericTransactionManagerLookup;
import org.infinispan.util.FileLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.w3c.dom.Element;
Deleted: trunk/core/src/main/java/org/infinispan/context/AbstractContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/AbstractContext.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/AbstractContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,172 +0,0 @@
-package org.infinispan.context;
-
-import org.infinispan.container.entries.CacheEntry;
-import org.infinispan.util.BidirectionalLinkedHashMap;
-import org.infinispan.util.BidirectionalMap;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Common features of transaction and invocation contexts
- *
- * @author Manik Surtani
- * @since 4.0
- */
-public abstract class AbstractContext {
-
- protected volatile EnumSet<Flag> flags;
-
- // these flags pertain to the context and are set internally. Not to be confused with Flag, which is set by user
- // invocations on AdvancedCache.
- protected byte contextFlags;
- protected BidirectionalLinkedHashMap<Object, CacheEntry> lookedUpEntries = null;
-
- protected static enum ContextFlags {
- FORCE_SYNCHRONOUS(1), FORCE_ASYNCHRONOUS(1 << 1), ORIGIN_LOCAL(1 << 2), LOCAL_ROLLBACK_ONLY(1 << 3),
- CONTAINS_MODS(1 << 4), CONTAINS_LOCKS(1 << 5);
- final byte mask;
-
- ContextFlags(int mask) {
- this.mask = (byte) mask;
- }
- }
-
- protected final boolean isContextFlagSet(ContextFlags flag) {
- return (contextFlags & flag.mask) != 0;
- }
-
- protected final void setContextFlag(ContextFlags flag) {
- contextFlags |= flag.mask;
- }
-
- protected final void unsetContextFlag(ContextFlags flag) {
- contextFlags &= ~flag.mask;
- }
-
- protected final void setContextFlag(ContextFlags flag, boolean value) {
- if (value)
- setContextFlag(flag);
- else
- unsetContextFlag(flag);
- }
-
- public boolean hasFlag(Flag o) {
- return flags != null && flags.contains(o);
- }
-
- public Set<Flag> getFlags() {
- return flags;
- }
-
- public void setFlags(Flag... flags) {
- if (flags == null || flags.length == 0) return;
- if (this.flags == null)
- this.flags = EnumSet.copyOf(Arrays.asList(flags));
- else
- this.flags.addAll(Arrays.asList(flags));
- }
-
- public void setFlags(Collection<Flag> flags) {
- if (flags == null || flags.size() == 0) return;
- if (this.flags == null)
- this.flags = EnumSet.copyOf(flags);
- else
- this.flags.addAll(flags);
- }
-
- public void resetFlags() {
- flags = null;
- }
-
- public boolean isFlagsUninitialized() {
- return flags == null;
- }
-
- protected abstract int getLockSetSize();
-
- public boolean hasLockedKey(Object key) {
- CacheEntry e = lookupEntry(key);
- return e != null && e.isChanged();
- }
-
- public CacheEntry lookupEntry(Object key) {
- return lookedUpEntries.get(key);
- }
-
- public void removeLookedUpEntry(Object key) {
- lookedUpEntries.remove(key);
- }
-
- public void putLookedUpEntry(Object key, CacheEntry entry) {
- lookedUpEntries.put(key, entry);
- }
-
- public void clearLookedUpEntries() {
- lookedUpEntries.clear();
- }
-
- public BidirectionalMap<Object, CacheEntry> getLookedUpEntries() {
- return lookedUpEntries;
- }
-
- public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
- lookedUpEntries.putAll(lookedUpEntries);
- }
-
- public void reset() {
- if (lookedUpEntries != null) lookedUpEntries.clear();
- flags = null;
- contextFlags = 0;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof AbstractContext)) return false;
-
- AbstractContext that = (AbstractContext) o;
-
- if (contextFlags != that.contextFlags) return false;
- if (lookedUpEntries != null ? !lookedUpEntries.equals(that.lookedUpEntries) : that.lookedUpEntries != null)
- return false;
- if (flags != null ? !flags.equals(that.flags) : that.flags != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = flags != null ? flags.hashCode() : 0;
- result = 31 * result + (int) contextFlags;
- result = 31 * result + (lookedUpEntries != null ? lookedUpEntries.hashCode() : 0);
- return result;
- }
-
- @SuppressWarnings("unchecked")
- protected void copyInto(AbstractContext ctx) {
- if (flags != null) ctx.flags = EnumSet.copyOf(flags);
- ctx.contextFlags = contextFlags;
- if (lookedUpEntries != null)
- ctx.lookedUpEntries = (BidirectionalLinkedHashMap<Object, CacheEntry>) lookedUpEntries.clone();
- }
-
- public boolean isContainsModifications() {
- return isContextFlagSet(ContextFlags.CONTAINS_MODS);
- }
-
- public void setContainsModifications(boolean b) {
- setContextFlag(ContextFlags.CONTAINS_MODS, b);
- }
-
- public boolean isContainsLocks() {
- return isContextFlagSet(ContextFlags.CONTAINS_LOCKS);
- }
-
- public void setContainsLocks(boolean b) {
- setContextFlag(ContextFlags.CONTAINS_LOCKS, b);
- }
-}
Deleted: trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,41 +0,0 @@
-package org.infinispan.context;
-
-import org.infinispan.remoting.transport.Address;
-
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A transaction context that adds behavior specific to DIST
- *
- * @author Manik Surtani
- * @since 4.0
- */
-public class DistTransactionContextImpl extends TransactionContextImpl {
-
- final Set<Address> participants = new HashSet<Address>();
-
- public DistTransactionContextImpl(Transaction tx) throws SystemException, RollbackException {
- super(tx);
- }
-
- @Override
- public Set<Address> getTransactionParticipants() {
- return participants;
- }
-
- @Override
- public void addTransactionParticipants(Collection<Address> addresses) {
- participants.addAll(addresses);
- }
-
- @Override
- public void reset() {
- super.reset();
- participants.clear();
- }
-}
Modified: trunk/core/src/main/java/org/infinispan/context/EntryLookup.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/EntryLookup.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/EntryLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -36,9 +36,6 @@
/**
* Retrieves an entry from the collection of looked up entries in the current scope.
* <p/>
- * If a transaction is in progress, implementations should delegate to the same method in {@link
- * TransactionContext}.
- * <p/>
*
* @param key key to look up
* @return an entry, or null if it cannot be found.
@@ -48,10 +45,6 @@
/**
* Retrieves a map of entries looked up within the current scope.
* <p/>
- * If a transaction is in progress, implementations should delegate to the same method in {@link
- * TransactionContext}.
- * <p/>
- *
* @return a map of looked up entries.
*/
BidirectionalMap<Object, CacheEntry> getLookedUpEntries();
@@ -59,9 +52,6 @@
/**
* Puts an entry in the registry of looked up entries in the current scope.
* <p/>
- * If a transaction is in progress, implementations should delegate to the same method in {@link
- * TransactionContext}.
- * <p/>
*
* @param key key to store
* @param e entry to store
@@ -78,7 +68,6 @@
void clearLookedUpEntries();
/**
- * Note that if a transaction is in scope, implementations should test this lock from on {@link TransactionContext}.
* Using this method should always ensure locks checked in the appropriate scope.
*
* @param key lock to test
@@ -86,23 +75,4 @@
*/
boolean hasLockedKey(Object key);
- /**
- * @return true if the context contains modifications, false otherwise
- */
- boolean isContainsModifications();
-
- /**
- * Sets whether modifications have been made in the current context
- */
- void setContainsModifications(boolean b);
-
- /**
- * @return true if the context contains locks, false otherwise
- */
- boolean isContainsLocks();
-
- /**
- * Sets whether locks have been acquired in the current context
- */
- void setContainsLocks(boolean b);
}
Modified: trunk/core/src/main/java/org/infinispan/context/InvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/InvocationContext.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/InvocationContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,44 +21,24 @@
*/
package org.infinispan.context;
-import org.infinispan.transaction.GlobalTransaction;
-
-import javax.transaction.Transaction;
-
/**
* A context that contains information pertaining to a given invocation. These contexts typically have the lifespan of
* a single invocation.
*
* @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @author Mircea.Markus at jboss.com
* @since 4.0
*/
-public interface InvocationContext extends EntryLookup, FlagContainer {
+public interface InvocationContext extends EntryLookup, FlagContainer, Cloneable {
- void setLocalRollbackOnly(boolean localRollbackOnly);
-
- Transaction getTransaction();
-
- void setTransaction(Transaction transaction);
-
- TransactionContext getTransactionContext();
-
- void setTransactionContext(TransactionContext transactionContext);
-
- GlobalTransaction getGlobalTransaction();
-
- void setGlobalTransaction(GlobalTransaction globalTransaction);
-
boolean isOriginLocal();
- void setOriginLocal(boolean originLocal);
+ boolean isInTxScope();
- boolean isLocalRollbackOnly();
+ Object getLockOwner();
- void reset();
+ public Object clone();
- InvocationContext copy();
+ boolean hasLockedEntries();
- void setState(InvocationContext template);
-
- boolean isValidTransaction();
}
Deleted: trunk/core/src/main/java/org/infinispan/context/InvocationContextContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/InvocationContextContainer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/InvocationContextContainer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,56 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.context;
-
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.factories.annotations.NonVolatile;
-import org.infinispan.factories.context.ContextFactory;
-import org.infinispan.factories.scopes.Scope;
-import org.infinispan.factories.scopes.Scopes;
-
-
-/**
- * Container and factory for thread locals
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 4.0
- */
- at NonVolatile
- at Scope(Scopes.NAMED_CACHE)
-public class InvocationContextContainer extends ThreadLocal<InvocationContext> {
- ContextFactory contextFactory;
-
- @Inject
- public void injectContextFactory(ContextFactory contextFactory) {
- this.contextFactory = contextFactory;
- }
-
- @Override
- protected final InvocationContext initialValue() {
- // create if this is initially unset
- return contextFactory.createInvocationContext();
- }
-
- public void reset() {
- set(initialValue());
- }
-}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/context/InvocationContextImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/InvocationContextImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/InvocationContextImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,311 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.context;
-
-import org.infinispan.container.entries.CacheEntry;
-import org.infinispan.transaction.GlobalTransaction;
-import org.infinispan.transaction.TransactionTable;
-import org.infinispan.util.BidirectionalLinkedHashMap;
-import org.infinispan.util.BidirectionalMap;
-import org.infinispan.util.InfinispanCollections;
-
-import javax.transaction.Transaction;
-import java.util.Map;
-
-public class InvocationContextImpl extends AbstractContext implements InvocationContext {
- private Transaction transaction;
- private GlobalTransaction globalTransaction;
- protected volatile TransactionContext transactionContext;
-
- public InvocationContextImpl() {
- // set this to true by default
- setContextFlag(ContextFlags.ORIGIN_LOCAL);
- }
-
- protected final int getLockSetSize() {
- // always use 4 for invocation locks
- return 4;
- }
-
- private void initLookedUpEntries() {
- if (lookedUpEntries == null) lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(4);
- }
-
- @Override
- public boolean hasLockedKey(Object key) {
- if (transactionContext != null) return transactionContext.hasLockedKey(key);
- return super.hasLockedKey(key);
- }
-
- @Override
- public CacheEntry lookupEntry(Object k) {
- if (transactionContext != null) {
- return transactionContext.lookupEntry(k);
- } else {
- return lookedUpEntries == null ? null : lookedUpEntries.get(k);
- }
- }
-
- @Override
- public void removeLookedUpEntry(Object key) {
- if (transactionContext != null) {
- transactionContext.removeLookedUpEntry(key);
- } else {
- if (lookedUpEntries != null) lookedUpEntries.remove(key);
- }
- }
-
- @Override
- public void putLookedUpEntry(Object key, CacheEntry e) {
- if (transactionContext != null)
- transactionContext.putLookedUpEntry(key, e);
- else {
- initLookedUpEntries();
- lookedUpEntries.put(key, e);
- }
- }
-
- @Override
- public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
- if (transactionContext != null)
- transactionContext.putLookedUpEntries(lookedUpEntries);
- else {
- initLookedUpEntries();
- this.lookedUpEntries.putAll(lookedUpEntries);
- }
- }
-
- @Override
- public void clearLookedUpEntries() {
- if (lookedUpEntries != null) lookedUpEntries.clear();
- }
-
- @SuppressWarnings("unchecked")
- public BidirectionalMap<Object, CacheEntry> getLookedUpEntries() {
- if (transactionContext != null) return transactionContext.getLookedUpEntries();
- return (BidirectionalMap<Object, CacheEntry>)
- (lookedUpEntries == null ? InfinispanCollections.emptyBidirectionalMap() : lookedUpEntries);
- }
-
- @SuppressWarnings("unchecked")
- public InvocationContext copy() {
- InvocationContextImpl copy = new InvocationContextImpl();
- copyInto(copy);
- copy.globalTransaction = globalTransaction;
- copy.transaction = transaction;
- copy.transactionContext = transactionContext;
- return copy;
- }
-
-
- /**
- * Marks teh context as only rolling back.
- *
- * @param localRollbackOnly if true, the context is only rolling back.
- */
- public void setLocalRollbackOnly(boolean localRollbackOnly) {
- setContextFlag(ContextFlags.LOCAL_ROLLBACK_ONLY, localRollbackOnly);
- }
-
- /**
- * Retrieves the transaction associated with this invocation
- *
- * @return The transaction associated with this invocation
- */
- public Transaction getTransaction() {
- return transaction;
- }
-
- /**
- * Sets a transaction object on the invocation context.
- *
- * @param transaction transaction to set
- */
- public void setTransaction(Transaction transaction) {
- this.transaction = transaction;
- }
-
- /**
- * @return the transaction entry associated with the current transaction, or null if the current thread is not
- * associated with a transaction.
- * @since 4.0
- */
- public TransactionContext getTransactionContext() {
- return transactionContext;
- }
-
- /**
- * Sets the transaction context to be associated with the current thread.
- *
- * @param transactionContext transaction context to set
- * @since 4.0
- */
- public void setTransactionContext(TransactionContext transactionContext) {
- this.transactionContext = transactionContext;
- }
-
- /**
- * Retrieves the global transaction associated with this invocation
- *
- * @return the global transaction associated with this invocation
- */
- public GlobalTransaction getGlobalTransaction() {
- return globalTransaction;
- }
-
- /**
- * Sets the global transaction associated with this invocation
- *
- * @param globalTransaction global transaction to set
- */
- public void setGlobalTransaction(GlobalTransaction globalTransaction) {
- this.globalTransaction = globalTransaction;
- }
-
- /**
- * Tests if this invocation originated locally or from a remote cache.
- *
- * @return true if the invocation originated locally.
- */
- public boolean isOriginLocal() {
- return isContextFlagSet(ContextFlags.ORIGIN_LOCAL);
- }
-
- /**
- * If set to true, the invocation is assumed to have originated locally. If set to false, assumed to have originated
- * from a remote cache.
- *
- * @param originLocal flag to set
- */
- public void setOriginLocal(boolean originLocal) {
- setContextFlag(ContextFlags.ORIGIN_LOCAL, originLocal);
- }
-
- /**
- * @return true if the current transaction is set to rollback only.
- */
- public boolean isLocalRollbackOnly() {
- return isContextFlagSet(ContextFlags.LOCAL_ROLLBACK_ONLY);
- }
-
- /**
- * Resets the context, freeing up any references.
- */
- public void reset() {
- super.reset();
- transaction = null;
- globalTransaction = null;
- transactionContext = null;
- setContextFlag(ContextFlags.ORIGIN_LOCAL);
- lookedUpEntries = null;
- }
-
- /**
- * Sets the state of the InvocationContext based on the template context passed in
- *
- * @param template template to copy from
- */
- public void setState(InvocationContext template) {
- if (template == null) {
- throw new NullPointerException("Template InvocationContext passed in to InvocationContext.setState() passed in is null");
- }
-
- this.setGlobalTransaction(template.getGlobalTransaction());
- this.setLocalRollbackOnly(template.isLocalRollbackOnly());
- this.setFlags(template.getFlags());
- this.setOriginLocal(template.isOriginLocal());
- this.setTransaction(template.getTransaction());
- }
-
- /**
- * @return true if there is current transaction associated with the invocation, and this transaction is in a valid
- * state.
- */
- public boolean isValidTransaction() {
- // ought to move to the transaction context
- return transaction != null && TransactionTable.isValid(transaction);
- }
-
- @Override
- public boolean isContainsModifications() {
- return transactionContext == null ? super.isContainsModifications() : transactionContext.isContainsModifications();
- }
-
- @Override
- public void setContainsModifications(boolean b) {
- if (transactionContext == null)
- super.setContainsModifications(b);
- else
- transactionContext.setContainsModifications(b);
- }
-
- @Override
- public boolean isContainsLocks() {
- return transactionContext == null ? super.isContainsLocks() : transactionContext.isContainsLocks();
- }
-
- @Override
- public void setContainsLocks(boolean b) {
- if (transactionContext == null)
- super.setContainsLocks(b);
- else
- transactionContext.setContainsLocks(b);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- if (!super.equals(o)) return false;
-
- InvocationContextImpl that = (InvocationContextImpl) o;
-
- if (globalTransaction != null ? !globalTransaction.equals(that.globalTransaction) : that.globalTransaction != null)
- return false;
- if (transaction != null ? !transaction.equals(that.transaction) : that.transaction != null) return false;
- if (transactionContext != null ? !transactionContext.equals(that.transactionContext) : that.transactionContext != null)
- return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + (transaction != null ? transaction.hashCode() : 0);
- result = 31 * result + (globalTransaction != null ? globalTransaction.hashCode() : 0);
- result = 31 * result + (transactionContext != null ? transactionContext.hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- return "InvocationContextImpl{" +
- "transaction=" + transaction +
- ", globalTransaction=" + globalTransaction +
- ", transactionContext=" + transactionContext +
- ", flags=" + flags +
- ", contextFlags=" + contextFlags +
- ", lookedUpEntries size=" + (lookedUpEntries == null ? 0 : lookedUpEntries.size()) +
- '}';
- }
-}
Deleted: trunk/core/src/main/java/org/infinispan/context/TransactionContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/TransactionContext.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/TransactionContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,182 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.context;
-
-import org.infinispan.commands.write.WriteCommand;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
-
-import javax.transaction.Transaction;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A context that contains information pertaining to a given transaction. These contexts typically have the lifespan of
- * the entire transaction.
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @see InvocationContext
- * @since 4.0
- */
-public interface TransactionContext extends EntryLookup, FlagContainer {
- /**
- * Adds a modification to the modification list.
- *
- * @param command modification
- */
- void addModification(WriteCommand command);
-
- /**
- * Returns all modifications. If there are no modifications in this transaction this method will return an empty
- * list.
- *
- * @return list of modifications.
- */
- List<WriteCommand> getModifications();
-
- /**
- * Adds a modification to the local modification list.
- *
- * @param command command to add to list. Should not be null.
- * @throws NullPointerException if the command to be added is null.
- */
- void addLocalModification(WriteCommand command);
-
- /**
- * Returns all modifications that have been invoked with the LOCAL cache mode option. These will also be in the
- * standard modification list.
- *
- * @return list of LOCAL modifications, or an empty list.
- */
- List<WriteCommand> getLocalModifications();
-
- /**
- * Adds the key that has been removed in the scope of the current transaction.
- *
- * @param key key that has been removed.
- * @throws NullPointerException if the key is null.
- */
- void addRemovedEntry(Object key);
-
- /**
- * Gets the list of removed keys.
- *
- * @return list of keys of entries removed in the current transaction scope. Note that this method will return an
- * empty list if nothing has been removed. The list returned is defensively copied.
- */
- List<Object> getRemovedEntries();
-
- /**
- * Sets the local transaction to be associated with this transaction context.
- *
- * @param tx JTA transaction to associate with.
- */
- void setTransaction(Transaction tx);
-
- void setGlobalTransaction(GlobalTransaction gtx);
-
- /**
- * Returns a local transaction associated with this context.
- *
- * @return a JTA transaction
- */
- Transaction getTransaction();
-
- /**
- * Gets the value of the forceAsyncReplication flag.
- *
- * @return true if the forceAsyncReplication flag is set to true.
- */
- boolean isForceAsyncReplication();
-
- /**
- * Sets the value of the forceAsyncReplication flag.
- *
- * @param forceAsyncReplication value of forceAsyncReplication
- */
- void setForceAsyncReplication(boolean forceAsyncReplication);
-
- /**
- * Gets the value of the forceSyncReplication flag.
- *
- * @return true if the forceAsyncReplication flag is set to true.
- */
- boolean isForceSyncReplication();
-
- /**
- * Sets the value of the forceSyncReplication flag.
- *
- * @param forceSyncReplication value of forceSyncReplication
- */
- void setForceSyncReplication(boolean forceSyncReplication);
-
- /**
- * Adds a key to the list of uninitialized entry keys created by the cache loader.
- *
- * @param key key to add. Must not be null.
- */
- void addDummyEntryCreatedByCacheLoader(Object key);
-
- /**
- * @return a list of uninitialized entries created by the cache loader, or an empty list.
- */
- List<Object> getDummyEntriesCreatedByCacheLoader();
-
- /**
- * @return true if modifications were registered.
- */
- boolean hasModifications();
-
- /**
- * @return true if any modifications have been invoked with cache mode being LOCAL.
- */
- boolean hasLocalModifications();
-
- /**
- * @return true if either there are modifications or local modifications that are not for replicating.
- */
- boolean hasAnyModifications();
-
- /**
- * Cleans up internal state, freeing up references.
- */
- void reset();
-
- GlobalTransaction getGobalTransaction();
-
- /**
- * Retrieves a set of Addresses of caches participating in a given transaction for a specific cache. Returns null if
- * the participation includes <i>all</i> caches in the cluster (e.g., you are using replication, invalidation or
- * local mode).
- *
- * @return a set of cache addresses
- */
- Set<Address> getTransactionParticipants();
-
- /**
- * Adds a transaction participant. This has no effect unless the cache mode used is DIST.
- *
- * @param addresses address to add
- */
- void addTransactionParticipants(Collection<Address> addresses);
-}
Deleted: trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,240 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.context;
-
-import org.infinispan.commands.write.WriteCommand;
-import org.infinispan.container.entries.CacheEntry;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
-import org.infinispan.util.BidirectionalLinkedHashMap;
-
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A transaction context specially geared to dealing with MVCC.
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 4.0
- */
-public class TransactionContextImpl extends AbstractContext implements TransactionContext {
- /**
- * Local transaction
- */
- private Transaction ltx = null;
-
- /**
- * List<VisitableCommand> of modifications. They will be replicated on TX commit
- */
- private List<WriteCommand> modificationList;
- /**
- * A list of modifications that have been encountered with a LOCAL mode option. These will be removed from the
- * modification list during replication.
- */
- private List<WriteCommand> localModifications;
-
- /**
- * A list of dummy uninitialised entries created by the cache loader interceptor to load data for a given entry in
- * this tx.
- */
- private List<Object> dummyEntriesCreatedByCacheLoader;
-
- /**
- * List<Object> of keys that have been removed by the transaction
- */
- private List<Object> removedKeys = null;
-
- private GlobalTransaction gtx;
-
- protected final int getLockSetSize() {
- // always initialize the lock collection to 8 entries
- return 8;
- }
-
- public TransactionContextImpl(Transaction tx) throws SystemException, RollbackException {
- ltx = tx;
- lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(8);
- }
-
- public void reset() {
- super.reset();
- modificationList = null;
- localModifications = null;
- if (dummyEntriesCreatedByCacheLoader != null) dummyEntriesCreatedByCacheLoader.clear();
- if (removedKeys != null) removedKeys.clear();
- lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(8);
- }
-
- public GlobalTransaction getGobalTransaction() {
- return gtx;
- }
-
- public Set<Address> getTransactionParticipants() {
- return null; // by default all caches in the cluster participate.
- }
-
- public void addTransactionParticipants(Collection<Address> addresses) {
- // no-op - meant for overriding
- }
-
- public void putLookedUpEntries(Map<Object, CacheEntry> entries) {
- lookedUpEntries.putAll(entries);
- }
-
- public void addModification(WriteCommand command) {
- if (command == null) return;
- if (modificationList == null) modificationList = new LinkedList<WriteCommand>();
- modificationList.add(command);
- }
-
- public List<WriteCommand> getModifications() {
- if (modificationList == null) return Collections.emptyList();
- return modificationList;
- }
-
- public void addLocalModification(WriteCommand command) {
- if (command == null) throw new NullPointerException("Command is null!");
- if (localModifications == null) localModifications = new LinkedList<WriteCommand>();
- localModifications.add(command);
- }
-
- public List<WriteCommand> getLocalModifications() {
- if (localModifications == null) return Collections.emptyList();
- return localModifications;
- }
-
-
- public void addRemovedEntry(Object key) {
- if (key == null) throw new NullPointerException("Key is null!");
- if (removedKeys == null) removedKeys = new LinkedList<Object>();
- removedKeys.add(key);
- }
-
- public List<Object> getRemovedEntries() {
- if (removedKeys == null) return Collections.emptyList();
- return new ArrayList<Object>(removedKeys);
- }
-
- public void setTransaction(Transaction tx) {
- ltx = tx;
- }
-
- public void setGlobalTransaction(GlobalTransaction gtx) {
- this.gtx = gtx;
- }
-
- public Transaction getTransaction() {
- return ltx;
- }
-
- public boolean isForceAsyncReplication() {
- return isContextFlagSet(ContextFlags.FORCE_ASYNCHRONOUS);
- }
-
- public void setForceAsyncReplication(boolean forceAsyncReplication) {
- setContextFlag(ContextFlags.FORCE_ASYNCHRONOUS, forceAsyncReplication);
- if (forceAsyncReplication) unsetContextFlag(ContextFlags.FORCE_SYNCHRONOUS);
- }
-
- public boolean isForceSyncReplication() {
- return isContextFlagSet(ContextFlags.FORCE_SYNCHRONOUS);
- }
-
- public void setForceSyncReplication(boolean forceSyncReplication) {
- setContextFlag(ContextFlags.FORCE_SYNCHRONOUS, forceSyncReplication);
- if (forceSyncReplication) unsetContextFlag(ContextFlags.FORCE_ASYNCHRONOUS);
- }
-
- /**
- * Returns debug information about this transaction.
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("TransactionContext (").append(System.identityHashCode(this)).append(") nmodificationList: ").append(modificationList);
- return sb.toString();
- }
-
- public void addDummyEntryCreatedByCacheLoader(Object key) {
- if (dummyEntriesCreatedByCacheLoader == null)
- dummyEntriesCreatedByCacheLoader = new LinkedList<Object>();
- dummyEntriesCreatedByCacheLoader.add(key);
- }
-
- public List<Object> getDummyEntriesCreatedByCacheLoader() {
- if (dummyEntriesCreatedByCacheLoader == null) return Collections.emptyList();
- return dummyEntriesCreatedByCacheLoader;
- }
-
- public boolean hasModifications() {
- return modificationList != null && !modificationList.isEmpty();
- }
-
- public boolean hasLocalModifications() {
- return localModifications != null && !localModifications.isEmpty();
- }
-
- public boolean hasAnyModifications() {
- return hasModifications() || hasLocalModifications();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- if (!super.equals(o)) return false;
-
- TransactionContextImpl that = (TransactionContextImpl) o;
-
- if (dummyEntriesCreatedByCacheLoader != null ? !dummyEntriesCreatedByCacheLoader.equals(that.dummyEntriesCreatedByCacheLoader) : that.dummyEntriesCreatedByCacheLoader != null)
- return false;
- if (gtx != null ? !gtx.equals(that.gtx) : that.gtx != null) return false;
- if (localModifications != null ? !localModifications.equals(that.localModifications) : that.localModifications != null)
- return false;
- if (ltx != null ? !ltx.equals(that.ltx) : that.ltx != null) return false;
- if (modificationList != null ? !modificationList.equals(that.modificationList) : that.modificationList != null)
- return false;
- if (removedKeys != null ? !removedKeys.equals(that.removedKeys) : that.removedKeys != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + (ltx != null ? ltx.hashCode() : 0);
- result = 31 * result + (modificationList != null ? modificationList.hashCode() : 0);
- result = 31 * result + (localModifications != null ? localModifications.hashCode() : 0);
- result = 31 * result + (dummyEntriesCreatedByCacheLoader != null ? dummyEntriesCreatedByCacheLoader.hashCode() : 0);
- result = 31 * result + (removedKeys != null ? removedKeys.hashCode() : 0);
- result = 31 * result + (gtx != null ? gtx.hashCode() : 0);
- return result;
- }
-}
Added: trunk/core/src/main/java/org/infinispan/context/container/InvocationContextContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/container/InvocationContextContainer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/container/InvocationContextContainer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,34 @@
+package org.infinispan.context.container;
+
+import org.infinispan.context.impl.InitiatorTxInvocationContext;
+import org.infinispan.context.impl.RemoteTxInvocationContext;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.factories.annotations.NonVolatile;
+import org.infinispan.factories.scopes.Scope;
+import org.infinispan.factories.scopes.Scopes;
+import org.infinispan.transaction.xa.GlobalTransaction;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+ at NonVolatile
+ at Scope(Scopes.NAMED_CACHE)
+public interface InvocationContextContainer {
+ InvocationContext getLocalInvocationContext(boolean prepareForCall);
+
+ InitiatorTxInvocationContext getInitiatorTxInvocationContext();
+
+ RemoteTxInvocationContext getRemoteTxInvocationContext(GlobalTransaction globalTransaction, boolean create);
+
+ InvocationContext getRemoteNonTxInvocationContext();
+
+ InvocationContext getThreadContext();
+
+ Object suspend();
+
+ void resume(Object backup);
+}
Property changes on: trunk/core/src/main/java/org/infinispan/context/container/InvocationContextContainer.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/context/container/ReplicationInvocationContextContainer.java (from rev 204, trunk/core/src/main/java/org/infinispan/invocation/InvocationContextContainer.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/container/ReplicationInvocationContextContainer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/container/ReplicationInvocationContextContainer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,157 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.context.container;
+
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.InitiatorTxInvocationContext;
+import org.infinispan.context.impl.NonTxInvocationContext;
+import org.infinispan.context.impl.RemoteTxInvocationContext;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.transaction.xa.TransactionXaAdapter;
+import org.infinispan.transaction.xa.TxEnlistingManager;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import javax.transaction.Transaction;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * Container and factory for thread locals
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 4.0
+ */
+public class ReplicationInvocationContextContainer implements InvocationContextContainer {
+
+ private static Log log = LogFactory.getLog(ReplicationInvocationContextContainer.class);
+
+ private TxEnlistingManager txEnlistingManager;
+
+
+ private ThreadLocal<PossibleContexts> contextsTl = new ThreadLocal<PossibleContexts>() {
+ @Override
+ protected PossibleContexts initialValue() {
+ return new PossibleContexts();
+ }
+ };
+
+ private Map<GlobalTransaction, RemoteTxInvocationContext> remoteTxMap = new ConcurrentHashMap<GlobalTransaction, RemoteTxInvocationContext>(20);
+
+ @Inject
+ public void init(TxEnlistingManager txEnlistingManager) {
+ this.txEnlistingManager = txEnlistingManager;
+ }
+
+ public InvocationContext getLocalInvocationContext(boolean prepareForCall) {
+ PossibleContexts contexts = contextsTl.get();
+ Transaction tx = txEnlistingManager.getRunningTx();
+ if (tx != null) {
+ contexts.initInitiatorInvicationContext();
+ InitiatorTxInvocationContext context = contexts.initiatorTxInvocationContext;
+ TransactionXaAdapter xaAdapter = txEnlistingManager.getXaCache(tx);
+ context.setXaCache(xaAdapter);
+ return contexts.updateThreadContextAndReturn(context);
+ } else {
+ contexts.initNonTxInvocationContext();
+ contexts.nonTxInvocationContext.setOriginLocal(true);
+ if (prepareForCall) contexts.nonTxInvocationContext.prepareForCall();
+ return contexts.updateThreadContextAndReturn(contexts.nonTxInvocationContext);
+ }
+ }
+
+ public InitiatorTxInvocationContext getInitiatorTxInvocationContext() {
+ PossibleContexts contexts = contextsTl.get();
+ contexts.initInitiatorInvicationContext();
+ contexts.updateThreadContextAndReturn(contexts.initiatorTxInvocationContext);
+ return contexts.initiatorTxInvocationContext;
+ }
+
+ public RemoteTxInvocationContext getRemoteTxInvocationContext(GlobalTransaction globalTransaction, boolean create) {
+ RemoteTxInvocationContext context = remoteTxMap.get(globalTransaction);
+ if (context == null && create) {
+ context = new RemoteTxInvocationContext();
+ if (log.isTraceEnabled()) log.trace("Rgistering remote tx: " + globalTransaction);
+ remoteTxMap.put(globalTransaction, context);
+ }
+ PossibleContexts contexts = contextsTl.get();
+ contexts.updateThreadContextAndReturn(context);
+ return context;
+ }
+
+ public InvocationContext getRemoteNonTxInvocationContext() {
+ PossibleContexts contexts = contextsTl.get();
+ contexts.initRemoteNonTxInvocationContext();
+ contexts.remoteNonTxContext.prepareForCall();
+ return contexts.updateThreadContextAndReturn(contexts.remoteNonTxContext);
+ }
+
+ public InvocationContext getThreadContext() {
+ InvocationContext invocationContext = contextsTl.get().threadInvocationContex;
+ if (invocationContext == null)
+ throw new IllegalStateException("This method can only be called after associating the current thread with a context");
+ return invocationContext;
+ }
+
+
+ public Object suspend() {
+ PossibleContexts result = contextsTl.get();
+ contextsTl.remove();
+ return result;
+ }
+
+ public void resume(Object backup) {
+ contextsTl.set((PossibleContexts) backup);
+ }
+
+ public static class PossibleContexts {
+ private NonTxInvocationContext nonTxInvocationContext;
+ private InitiatorTxInvocationContext initiatorTxInvocationContext;
+ private NonTxInvocationContext remoteNonTxContext;
+ private InvocationContext threadInvocationContex;
+
+ public void initInitiatorInvicationContext() {
+ if (initiatorTxInvocationContext == null) {
+ initiatorTxInvocationContext = new InitiatorTxInvocationContext();
+ }
+ }
+
+ public void initNonTxInvocationContext() {
+ if (nonTxInvocationContext == null) {
+ nonTxInvocationContext = new NonTxInvocationContext();
+ }
+ }
+
+ public void initRemoteNonTxInvocationContext() {
+ if (remoteNonTxContext == null) {
+ remoteNonTxContext = new NonTxInvocationContext();
+ }
+ }
+
+ public InvocationContext updateThreadContextAndReturn(InvocationContext ic) {
+ threadInvocationContex = ic;
+ return ic;
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/context/container/ReplicationInvocationContextContainer.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java (from rev 204, trunk/core/src/main/java/org/infinispan/context/AbstractContext.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,85 @@
+package org.infinispan.context.impl;
+
+import org.infinispan.container.entries.CacheEntry;
+import org.infinispan.context.Flag;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.util.BidirectionalMap;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * Common features of transaction and invocation contexts
+ *
+ * @author Manik Surtani
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public abstract class AbstractInvocationContext implements InvocationContext {
+
+ protected volatile EnumSet<Flag> flags;
+
+ public boolean hasFlag(Flag o) {
+ return flags != null && flags.contains(o);
+ }
+
+ public Set<Flag> getFlags() {
+ return flags;
+ }
+
+ public void setFlags(Flag... flags) {
+ if (flags == null || flags.length == 0) return;
+ if (this.flags == null)
+ this.flags = EnumSet.copyOf(Arrays.asList(flags));
+ else
+ this.flags.addAll(Arrays.asList(flags));
+ }
+
+ public void setFlags(Collection<Flag> flags) {
+ if (flags == null || flags.size() == 0) return;
+ if (this.flags == null)
+ this.flags = EnumSet.copyOf(flags);
+ else
+ this.flags.addAll(flags);
+ }
+
+ public void resetFlags() {
+ flags = null;
+ }
+
+ public boolean isFlagsUninitialized() {
+ return flags == null;
+ }
+
+ public boolean hasLockedKey(Object key) {
+ CacheEntry e = lookupEntry(key);
+ return e != null && e.isChanged();
+ }
+
+ public boolean hasLockedEntries() {
+ BidirectionalMap<Object, CacheEntry> lookedUpEntries = getLookedUpEntries();
+ boolean result = false;
+ for (CacheEntry e : lookedUpEntries.values()) {
+ if (e.isChanged()) {
+ System.out.println("Entry is locked = " + e);
+ result = true;
+ }
+ }
+ return result;
+ }
+
+
+ @Override
+ public Object clone() {
+ try {
+ AbstractInvocationContext dolly = (AbstractInvocationContext) super.clone();
+ if (flags != null)
+ dolly.flags = flags.clone();
+ return dolly;
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException("Imposible!");
+ }
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,105 @@
+package org.infinispan.context.impl;
+
+import org.infinispan.CacheException;
+import org.infinispan.remoting.transport.Address;
+
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import java.util.Set;
+import java.util.Collections;
+import java.util.List;
+import java.util.HashSet;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public abstract class AbstractTxInvocationContext extends AbstractInvocationContext implements TxInvocationContext {
+
+ protected Set<Address> txParticipants = null;
+
+ public boolean hasModifications() {
+ return getModifications() != null && !getModifications().isEmpty();
+ }
+
+ public Set<Address> getTransactionParticipants() {
+ return txParticipants == null ? Collections.EMPTY_SET : txParticipants;
+ }
+
+ public boolean isValidRunningTx() {
+ return isValid(getRunningTransaction());
+ }
+
+ public void addTransactionParticipants(List<Address> addresses) {
+ if (txParticipants == null) {
+ txParticipants = new HashSet<Address>();
+ }
+ txParticipants.addAll(addresses);
+ }
+
+
+ /**
+ * Return s true of tx's status is ACTIVE or PREPARING
+ *
+ * @param tx
+ * @return true if the tx is active or preparing
+ */
+ public static boolean isValid(Transaction tx) {
+ return isActive(tx) || isPreparing(tx);
+ }
+
+ /**
+ * Returns true if transaction is ACTIVE, false otherwise
+ */
+ public static boolean isActive(Transaction tx) {
+ if (tx == null) return false;
+ int status;
+ try {
+ status = tx.getStatus();
+ return status == Status.STATUS_ACTIVE;
+ }
+ catch (SystemException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if transaction is PREPARING, false otherwise
+ */
+ public static boolean isPreparing(Transaction tx) {
+ if (tx == null) return false;
+ int status;
+ try {
+ status = tx.getStatus();
+ return status == Status.STATUS_PREPARING;
+ }
+ catch (SystemException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether the caller is in a valid transaction. If not, will throw a CacheException.
+ */
+ public static void assertTransactionValid(TxInvocationContext ctx) {
+ Transaction tx = ctx.getRunningTransaction();
+ if (!isValid(tx)) try {
+ throw new CacheException("Invalid transaction " + tx + ", status = " + (tx == null ? null : tx.getStatus()));
+ }
+ catch (SystemException e) {
+ throw new CacheException("Exception trying to analyse status of transaction " + tx, e);
+ }
+ }
+
+ @Override
+ public Object clone() {
+ AbstractTxInvocationContext dolly = (AbstractTxInvocationContext) super.clone();
+ if (this.txParticipants != null) {
+ dolly.txParticipants = new HashSet<Address>(txParticipants);
+ }
+ return dolly;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/context/impl/InitiatorTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/InitiatorTxInvocationContext.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/impl/InitiatorTxInvocationContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,79 @@
+package org.infinispan.context.impl;
+
+import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.container.entries.CacheEntry;
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.transaction.xa.TransactionXaAdapter;
+import org.infinispan.util.BidirectionalMap;
+
+import javax.transaction.Transaction;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public class InitiatorTxInvocationContext extends AbstractTxInvocationContext {
+
+ private TransactionXaAdapter xaAdapter;
+
+ public Transaction getRunningTransaction() {
+ return xaAdapter.getTransaction();
+ }
+
+ public boolean isOriginLocal() {
+ return true;
+ }
+
+ public boolean isInTxScope() {
+ return true;
+ }
+
+ public Object getLockOwner() {
+ return xaAdapter.getTransactionIdentifier();
+ }
+
+ public GlobalTransaction getClusterTransactionId() {
+ return xaAdapter.getTransactionIdentifier();
+ }
+
+ public List<WriteCommand> getModifications() {
+ return xaAdapter.getModifications();
+ }
+
+ public void setXaCache(TransactionXaAdapter xaAdapter) {
+ this.xaAdapter = xaAdapter;
+ }
+
+ public CacheEntry lookupEntry(Object key) {
+ return xaAdapter != null ? xaAdapter.lookupEntry(key) : null;
+ }
+
+ public BidirectionalMap<Object, CacheEntry> getLookedUpEntries() {
+ return xaAdapter.getLookedUpEntries();
+ }
+
+ public void putLookedUpEntry(Object key, CacheEntry e) {
+ xaAdapter.putLookedUpEntry(key, e);
+ }
+
+ public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
+ xaAdapter.putLookedUpEntries(lookedUpEntries);
+ }
+
+ public void removeLookedUpEntry(Object key) {
+ xaAdapter.removeLookedUpEntry(key);
+ }
+
+ public void clearLookedUpEntries() {
+ xaAdapter.clearLookedUpEntries();
+ }
+
+ @Override
+ public Object clone() {
+ return super.clone();
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/context/impl/InitiatorTxInvocationContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,83 @@
+package org.infinispan.context.impl;
+
+import org.infinispan.container.entries.CacheEntry;
+import org.infinispan.util.BidirectionalMap;
+import org.infinispan.util.InfinispanCollections;
+import org.infinispan.util.BidirectionalLinkedHashMap;
+
+import java.util.Map;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public class NonTxInvocationContext extends AbstractInvocationContext {
+
+ private boolean isOriginLocal;
+
+ protected BidirectionalLinkedHashMap<Object, CacheEntry> lookedUpEntries = null;
+
+ public CacheEntry lookupEntry(Object k) {
+ return lookedUpEntries == null ? null : lookedUpEntries.get(k);
+ }
+
+ public void removeLookedUpEntry(Object key) {
+ if (lookedUpEntries != null) lookedUpEntries.remove(key);
+ }
+
+ public void putLookedUpEntry(Object key, CacheEntry e) {
+ initLookedUpEntries();
+ lookedUpEntries.put(key, e);
+ }
+
+ public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
+ initLookedUpEntries();
+ this.lookedUpEntries.putAll(lookedUpEntries);
+ }
+
+ public void clearLookedUpEntries() {
+ if (lookedUpEntries != null) lookedUpEntries.clear();
+ }
+
+ @SuppressWarnings("unchecked")
+ public BidirectionalMap<Object, CacheEntry> getLookedUpEntries() {
+ return (BidirectionalMap<Object, CacheEntry>)
+ (lookedUpEntries == null ? InfinispanCollections.emptyBidirectionalMap() : lookedUpEntries);
+ }
+
+ public boolean isOriginLocal() {
+ return isOriginLocal;
+ }
+
+ public void setOriginLocal(boolean originLocal) {
+ isOriginLocal = originLocal;
+ }
+
+ public boolean isInTxScope() {
+ return false;
+ }
+
+ public Object getLockOwner() {
+ return Thread.currentThread();
+ }
+
+ private void initLookedUpEntries() {
+ if (lookedUpEntries == null) lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(4);
+ }
+
+ public void prepareForCall() {
+ resetFlags();
+ clearLookedUpEntries();
+ }
+
+ @Override
+ public Object clone() {
+ NonTxInvocationContext dolly = (NonTxInvocationContext) super.clone();
+ if (lookedUpEntries != null) {
+ dolly.lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(lookedUpEntries);
+ }
+ return dolly;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,123 @@
+package org.infinispan.context.impl;
+
+import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.container.entries.CacheEntry;
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.util.BidirectionalMap;
+import org.infinispan.util.BidirectionalLinkedHashMap;
+
+import javax.transaction.Transaction;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public class RemoteTxInvocationContext extends AbstractTxInvocationContext {
+
+ private List<WriteCommand> modifications;
+
+ private BidirectionalMap<Object, CacheEntry> lookedUpEntries;
+
+ protected GlobalTransaction tx;
+
+ public RemoteTxInvocationContext() {
+ }
+
+ public Transaction getRunningTransaction() {
+ throw new IllegalStateException("this method can only be called for locally originated transactions!");
+ }
+
+ public Object getLockOwner() {
+ return tx;
+ }
+
+ public GlobalTransaction getClusterTransactionId() {
+ return tx;
+ }
+
+ public boolean isInTxScope() {
+ return true;
+ }
+
+ public boolean isOriginLocal() {
+ return false;
+ }
+
+ public List<WriteCommand> getModifications() {
+ return modifications;
+ }
+
+ public void initialize(WriteCommand[] modifications, GlobalTransaction tx) {
+ this.modifications = Arrays.asList(modifications);
+ lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(modifications.length);
+ this.tx = tx;
+ }
+
+ public CacheEntry lookupEntry(Object key) {
+ return lookedUpEntries.get(key);
+ }
+
+ public BidirectionalMap<Object, CacheEntry> getLookedUpEntries() {
+ return lookedUpEntries;
+ }
+
+ public void putLookedUpEntry(Object key, CacheEntry e) {
+ lookedUpEntries.put(key, e);
+ }
+
+ public void removeLookedUpEntry(Object key) {
+ lookedUpEntries.remove(key);
+ }
+
+ public void clearLookedUpEntries() {
+ lookedUpEntries.clear();
+ }
+
+ public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
+ lookedUpEntries.putAll(lookedUpEntries);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof RemoteTxInvocationContext)) return false;
+
+ RemoteTxInvocationContext context = (RemoteTxInvocationContext) o;
+ return tx.equals(context.tx);
+ }
+
+ @Override
+ public int hashCode() {
+ return tx.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "RemoteTxInvocationContext{" +
+ "modifications=" + modifications +
+ ", lookedUpEntries=" + lookedUpEntries +
+ ", tx=" + tx +
+ "} " + super.toString();
+ }
+
+ @Override
+ public Object clone() {
+ RemoteTxInvocationContext dolly = (RemoteTxInvocationContext) super.clone();
+ if (modifications != null) {
+ dolly.modifications = new ArrayList<WriteCommand>(modifications);
+ }
+ if (lookedUpEntries != null) {
+ dolly.lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(lookedUpEntries);
+ }
+ if (tx != null) {
+ dolly.tx = (GlobalTransaction) tx.clone();
+ }
+ return dolly;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,33 @@
+package org.infinispan.context.impl;
+
+import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.transaction.xa.GlobalTransaction;
+
+import javax.transaction.Transaction;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public interface TxInvocationContext extends InvocationContext {
+
+ public boolean hasModifications();
+
+ Set<Address> getTransactionParticipants();
+
+ GlobalTransaction getClusterTransactionId();
+
+ List<WriteCommand> getModifications();
+
+ Transaction getRunningTransaction();
+
+ boolean isValidRunningTx();
+
+ void addTransactionParticipants(List<Address> addresses);
+}
Property changes on: trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -12,9 +12,9 @@
import org.infinispan.notifications.cachemanagerlistener.CacheManagerNotifier;
import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged;
import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent;
-import org.infinispan.remoting.ResponseFilter;
-import org.infinispan.remoting.ResponseMode;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.remoting.responses.ClusteredGetResponseValidityFilter;
import org.infinispan.remoting.responses.Response;
import org.infinispan.remoting.responses.SuccessfulResponse;
Modified: trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -32,7 +32,6 @@
import org.infinispan.factories.annotations.NonVolatile;
import org.infinispan.factories.annotations.Start;
import org.infinispan.factories.annotations.Stop;
-import org.infinispan.factories.context.ContextMetaFactory;
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.lifecycle.ComponentStatus;
@@ -157,7 +156,6 @@
s.add(MarshallerFactory.class);
s.add(ResponseGeneratorFactory.class);
s.add(DistributionManagerFactory.class);
- s.add(ContextMetaFactory.class);
return s;
}
Modified: trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -7,6 +7,7 @@
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.notifications.cachemanagerlistener.CacheManagerNotifier;
import org.infinispan.remoting.InboundInvocationHandler;
+import org.infinispan.transaction.xa.TxEnlistingManager;
/**
* Factory for building global-scope components which have default empty constructors
@@ -15,7 +16,7 @@
* @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
* @since 4.0
*/
- at DefaultFactoryFor(classes = {InboundInvocationHandler.class, CacheManagerNotifier.class, RemoteCommandFactory.class})
+ at DefaultFactoryFor(classes = {InboundInvocationHandler.class, CacheManagerNotifier.class, RemoteCommandFactory.class, TxEnlistingManager.class})
@Scope(Scopes.GLOBAL)
public class EmptyConstructorFactory extends AbstractComponentFactory implements AutoInstantiableFactory {
public <T> T construct(Class<T> componentType) {
Modified: trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -25,15 +25,16 @@
import org.infinispan.batch.BatchContainer;
import org.infinispan.commands.CommandsFactory;
import org.infinispan.config.ConfigurationException;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.context.container.ReplicationInvocationContextContainer;
import org.infinispan.eviction.EvictionManager;
import org.infinispan.factories.annotations.DefaultFactoryFor;
import org.infinispan.loaders.CacheLoaderManager;
import org.infinispan.marshall.Marshaller;
import org.infinispan.marshall.VersionAwareMarshaller;
import org.infinispan.notifications.cachelistener.CacheNotifier;
+import org.infinispan.remoting.rpc.CacheRpcManager;
import org.infinispan.transaction.TransactionLog;
-import org.infinispan.transaction.TransactionTable;
/**
* Simple factory that just uses reflection and an empty constructor of the component type.
@@ -42,8 +43,8 @@
* @since 4.0
*/
@DefaultFactoryFor(classes = {CacheNotifier.class, EntryFactory.class, CommandsFactory.class,
- CacheLoaderManager.class, InvocationContextContainer.class,
- TransactionTable.class, BatchContainer.class, TransactionLog.class, EvictionManager.class})
+ CacheLoaderManager.class, InvocationContextContainer.class, CacheRpcManager.class,
+ BatchContainer.class, TransactionLog.class, EvictionManager.class, InvocationContextContainer.class})
public class EmptyConstructorNamedCacheFactory extends AbstractNamedCacheComponentFactory implements AutoInstantiableFactory {
@Override
public <T> T construct(Class<T> componentType) {
@@ -52,6 +53,8 @@
Class componentImpl;
if (componentType.equals(Marshaller.class)) {
componentImpl = VersionAwareMarshaller.class;
+ } else if (componentType.equals(InvocationContextContainer.class)) {
+ componentImpl = ReplicationInvocationContextContainer.class;
} else {
// add an "Impl" to the end of the class name and try again
componentImpl = getClass().getClassLoader().loadClass(componentType.getName() + "Impl");
Modified: trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -85,7 +85,7 @@
// do not bother wrapping though if this is not in a tx. repeatable read etc are all meaningless unless there is a tx.
// TODO: Do we need to wrap for reading even IN a TX if we are using read-committed?
- if (ctx.getTransaction() == null) {
+ if (!ctx.isInTxScope()) {
if (cacheEntry != null) ctx.putLookedUpEntry(key, cacheEntry);
return cacheEntry;
} else {
@@ -129,7 +129,7 @@
if (mvccEntry != cacheEntry) mvccEntry = (MVCCEntry) cacheEntry;
mvccEntry.setRemoved(false);
mvccEntry.setValid(true);
- }
+ }
return mvccEntry;
@@ -178,7 +178,7 @@
* @return true if a lock was needed and acquired, false if it didn't need to acquire the lock (i.e., lock was
* already held)
* @throws InterruptedException if interrupted
- * @throws org.infinispan.util.concurrent.TimeoutException
+ * @throws org.infinispan.lock.TimeoutException
* if we are unable to acquire the lock after a specified timeout.
*/
public final boolean acquireLock(InvocationContext ctx, Object key) throws InterruptedException, TimeoutException {
@@ -196,7 +196,7 @@
} else {
Object owner = lockManager.getOwner(key);
throw new TimeoutException("Unable to acquire lock on key [" + key + "] after [" + getLockAcquisitionTimeout(ctx)
- + "] milliseconds for requestor [" + lockManager.getLockOwner(ctx) + "]! Lock held by [" + owner + "]");
+ + "] milliseconds for requestor [" + ctx.getLockOwner() + "]! Lock held by [" + owner + "]");
}
}
Modified: trunk/core/src/main/java/org/infinispan/factories/RpcManagerFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/RpcManagerFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/RpcManagerFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,7 +23,7 @@
import org.infinispan.config.RuntimeConfig;
import org.infinispan.factories.annotations.DefaultFactoryFor;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
/**
* An extension of the EmptyConstructorFactory that places a component in the {@link RuntimeConfig} after creating it.
Modified: trunk/core/src/main/java/org/infinispan/factories/TransactionManagerFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/TransactionManagerFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/TransactionManagerFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,8 +23,8 @@
import org.infinispan.config.ConfigurationException;
import org.infinispan.factories.annotations.DefaultFactoryFor;
-import org.infinispan.transaction.BatchModeTransactionManager;
-import org.infinispan.transaction.TransactionManagerLookup;
+import org.infinispan.transaction.tm.BatchModeTransactionManager;
+import org.infinispan.transaction.lookup.TransactionManagerLookup;
import javax.transaction.TransactionManager;
Deleted: trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,36 +0,0 @@
-package org.infinispan.factories.context;
-
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
-import org.infinispan.factories.scopes.Scope;
-import org.infinispan.factories.scopes.Scopes;
-
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-
-/**
- * A factory for contexts
- *
- * @author Manik Surtani
- * @since 4.0
- */
- at Scope(Scopes.NAMED_CACHE)
-public interface ContextFactory {
-
- /**
- * @return a new invocation context
- */
- InvocationContext createInvocationContext();
-
-
- /**
- * @param tx JTA transaction to associate the new context with
- * @return a new transaction context
- * @throws javax.transaction.RollbackException
- * in the event of an invalid transaaction
- * @throws javax.transaction.SystemException
- * in the event of an invalid transaction
- */
- TransactionContext createTransactionContext(Transaction tx) throws SystemException, RollbackException;
-}
Deleted: trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,23 +0,0 @@
-package org.infinispan.factories.context;
-
-import org.infinispan.factories.AbstractNamedCacheComponentFactory;
-import org.infinispan.factories.AutoInstantiableFactory;
-import org.infinispan.factories.annotations.DefaultFactoryFor;
-
-/**
- * Builds a context factory
- *
- * @author Manik Surtani
- * @since 4.0
- */
- at DefaultFactoryFor(classes = ContextFactory.class)
-public class ContextMetaFactory extends AbstractNamedCacheComponentFactory implements AutoInstantiableFactory {
-
- @SuppressWarnings("unchecked")
- public <T> T construct(Class<T> componentType) {
- if (configuration.getCacheMode().isDistributed())
- return (T) new DistContextFactory();
- else
- return (T) new DefaultContextFactory();
- }
-}
Deleted: trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,59 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.factories.context;
-
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextImpl;
-import org.infinispan.context.TransactionContext;
-import org.infinispan.context.TransactionContextImpl;
-
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-
-/**
- * This is the factory responsible for creating {@link InvocationContext}s and {@link TransactionContext}s for requests,
- * based on the configuration used.
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 4.0
- */
-public class DefaultContextFactory implements ContextFactory {
- /**
- * @return a new invocation context
- */
- public InvocationContext createInvocationContext() {
- return new InvocationContextImpl();
- }
-
- /**
- * @param tx JTA transaction to associate the new context with
- * @return a new transaction context
- * @throws javax.transaction.RollbackException
- * in the event of an invalid transaaction
- * @throws javax.transaction.SystemException
- * in the event of an invalid transaction
- */
- public TransactionContext createTransactionContext(Transaction tx) throws SystemException, RollbackException {
- return new TransactionContextImpl(tx);
- }
-}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,22 +0,0 @@
-package org.infinispan.factories.context;
-
-import org.infinispan.context.DistTransactionContextImpl;
-import org.infinispan.context.TransactionContext;
-
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-
-/**
- * A context factory specific to DIST contexts
- *
- * @author Manik Surtani
- * @since 4.0
- */
-public class DistContextFactory extends DefaultContextFactory {
-
- @Override
- public TransactionContext createTransactionContext(Transaction tx) throws SystemException, RollbackException {
- return new DistTransactionContextImpl(tx);
- }
-}
Deleted: trunk/core/src/main/java/org/infinispan/interceptors/BaseTransactionalContextInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/BaseTransactionalContextInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/BaseTransactionalContextInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,87 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.interceptors;
-
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.transaction.GlobalTransaction;
-import org.infinispan.transaction.TransactionTable;
-
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-/**
- * Class providing some base functionality around manipulating transactions and global transactions withing invocation
- * contexts.
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
- * @since 4.0
- */
-public abstract class BaseTransactionalContextInterceptor extends CommandInterceptor {
- protected TransactionTable txTable;
- protected TransactionManager txManager;
-
- @Inject
- public void injectDependencies(TransactionTable txTable, TransactionManager txManager) {
- this.txManager = txManager;
- this.txTable = txTable;
- }
-
- protected void setTransactionalContext(Transaction tx, GlobalTransaction gtx, TransactionContext tCtx, InvocationContext ctx) {
- if (trace) {
- log.trace("Setting up transactional context.");
- log.trace("Setting tx as " + tx + " and gtx as " + gtx);
- }
- ctx.setTransaction(tx);
- ctx.setGlobalTransaction(gtx);
- if (tCtx == null) {
- if (gtx != null) {
- ctx.setTransactionContext(txTable.getTransactionContext(gtx));
- } else if (tx == null) {
- // then nullify the transaction tCtx as well
- ctx.setTransactionContext(null);
- }
- } else {
- ctx.setTransactionContext(tCtx);
- }
- }
-
- /**
- * Returns true if transaction is rolling back, false otherwise
- */
- protected boolean isRollingBack(Transaction tx) {
- if (tx == null) return false;
- int status;
- try {
- status = tx.getStatus();
- return status == Status.STATUS_ROLLING_BACK || status == Status.STATUS_ROLLEDBACK;
- }
- catch (SystemException e) {
- log.error("failed getting transaction status", e);
- return false;
- }
- }
-}
\ No newline at end of file
Modified: trunk/core/src/main/java/org/infinispan/interceptors/BatchingInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/BatchingInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/BatchingInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -24,6 +24,7 @@
import org.infinispan.batch.BatchContainer;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.interceptors.base.CommandInterceptor;
@@ -39,11 +40,13 @@
public class BatchingInterceptor extends CommandInterceptor {
BatchContainer batchContainer;
TransactionManager transactionManager;
+ InvocationContextContainer icc;
@Inject
- private void inject(BatchContainer batchContainer, TransactionManager transactionManager) {
+ private void inject(BatchContainer batchContainer, TransactionManager transactionManager, InvocationContextContainer icc) {
this.batchContainer = batchContainer;
this.transactionManager = transactionManager;
+ this.icc = icc;
}
/**
@@ -53,18 +56,20 @@
*/
@Override
protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
- Transaction tx = null;
- try {
- // if in a batch, attach tx
- if (transactionManager.getTransaction() == null &&
- (tx = batchContainer.getBatchTransaction()) != null) {
+ Transaction tx;
+ if (!ctx.isOriginLocal()) return invokeNextInterceptor(ctx, command);
+ // if in a batch, attach tx
+ if (transactionManager.getTransaction() == null && (tx = batchContainer.getBatchTransaction()) != null) {
+ try {
transactionManager.resume(tx);
+ //this will make the call with a tx invocation context
+ return invokeNextInterceptor(icc.getLocalInvocationContext(true), command);
+ } finally {
+ if (transactionManager.getTransaction() != null && batchContainer.isSuspendTxAfterInvocation())
+ transactionManager.suspend();
}
- return super.handleDefault(ctx, command);
+ } else {
+ return invokeNextInterceptor(ctx, command);
}
- finally {
- if (tx != null && transactionManager.getTransaction() != null && batchContainer.isSuspendTxAfterInvocation())
- transactionManager.suspend();
- }
}
}
Modified: trunk/core/src/main/java/org/infinispan/interceptors/CacheLoaderInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/CacheLoaderInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/CacheLoaderInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -129,7 +129,6 @@
// Reuse the lock and create a new entry for loading
MVCCEntry n = entryFactory.wrapEntryForWriting(ctx, key, true, false, keyLocked, false);
n = loadEntry(ctx, key, n);
- ctx.setContainsModifications(true);
return true;
} else {
return true;
Modified: trunk/core/src/main/java/org/infinispan/interceptors/CacheStoreInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/CacheStoreInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/CacheStoreInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -38,7 +38,7 @@
import org.infinispan.container.entries.InternalEntryFactory;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.interceptors.base.JmxStatsCommandInterceptor;
@@ -50,12 +50,10 @@
import org.infinispan.loaders.modifications.Modification;
import org.infinispan.loaders.modifications.Remove;
import org.infinispan.loaders.modifications.Store;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.logging.LogFactory;
-import javax.transaction.SystemException;
import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -74,7 +72,6 @@
*/
public class CacheStoreInterceptor extends JmxStatsCommandInterceptor {
private CacheLoaderManagerConfig loaderConfig = null;
- private TransactionManager txMgr = null;
private HashMap<Transaction, Integer> txStores = new HashMap<Transaction, Integer>();
private Map<Transaction, Set<Object>> preparingTxs = new ConcurrentHashMap<Transaction, Set<Object>>();
private final AtomicLong cacheStores = new AtomicLong(0);
@@ -88,9 +85,8 @@
}
@Inject
- protected void init(CacheLoaderManager loaderManager, TransactionManager txManager) {
+ protected void init(CacheLoaderManager loaderManager) {
this.loaderManager = loaderManager;
- txMgr = txManager;
}
@Start(priority = 15)
@@ -114,11 +110,11 @@
}
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
- if (!skip(ctx, command) && inTransaction()) {
- if (ctx.getTransactionContext().hasAnyModifications()) {
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
+ if (!skip(ctx, command)) {
+ if (ctx.hasModifications()) {
// this is a commit call.
- Transaction tx = ctx.getTransaction();
+ Transaction tx = ctx.getRunningTransaction();
log.trace("Calling loader.commit() for transaction {0}", tx);
try {
store.commit(tx);
@@ -143,11 +139,11 @@
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
- if (!skip(ctx, command) && inTransaction()) {
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
+ if (!skip(ctx, command)) {
if (trace) log.trace("transactional so don't put stuff in the cloader yet.");
- if (ctx.getTransactionContext().hasAnyModifications()) {
- Transaction tx = ctx.getTransaction();
+ if (ctx.hasModifications()) {
+ Transaction tx = ctx.getRunningTransaction();
// this is a rollback method
if (preparingTxs.containsKey(tx)) {
preparingTxs.remove(tx);
@@ -162,10 +158,10 @@
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
- if (!skip(ctx, command) && inTransaction()) {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
+ if (!skip(ctx, command)) {
if (trace) log.trace("transactional so don't put stuff in the cloader yet.");
- prepareCacheLoader(ctx, command.getGlobalTransaction(), ctx.getTransactionContext(), command.isOnePhaseCommit());
+ prepareCacheLoader(ctx, command.getGlobalTransaction(), ctx, command.isOnePhaseCommit());
}
return invokeNextInterceptor(ctx, command);
}
@@ -173,7 +169,7 @@
@Override
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
Object retval = invokeNextInterceptor(ctx, command);
- if (!skip(ctx, command) && !inTransaction() && command.isSuccessful()) {
+ if (!skip(ctx, command) && !ctx.isInTxScope() && command.isSuccessful()) {
Object key = command.getKey();
boolean resp = store.remove(key);
log.trace("Removed entry under key {0} and got response {1} from CacheStore", key, resp);
@@ -183,7 +179,7 @@
@Override
public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
- if (!skip(ctx, command) && !inTransaction()) {
+ if (!skip(ctx, command) && !ctx.isInTxScope()) {
store.clear();
log.trace("Cleared cache store");
}
@@ -193,7 +189,7 @@
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
Object returnValue = invokeNextInterceptor(ctx, command);
- if (skip(ctx, command) || inTransaction() || !command.isSuccessful()) return returnValue;
+ if (skip(ctx, command) || ctx.isInTxScope() || !command.isSuccessful()) return returnValue;
Object key = command.getKey();
InternalCacheEntry se = getStoredEntry(key, ctx);
@@ -207,7 +203,7 @@
@Override
public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
Object returnValue = invokeNextInterceptor(ctx, command);
- if (skip(ctx, command) || inTransaction() || !command.isSuccessful()) return returnValue;
+ if (skip(ctx, command) || ctx.isInTxScope() || !command.isSuccessful()) return returnValue;
Object key = command.getKey();
InternalCacheEntry se = getStoredEntry(key, ctx);
@@ -221,7 +217,7 @@
@Override
public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
Object returnValue = invokeNextInterceptor(ctx, command);
- if (skip(ctx, command) || inTransaction()) return returnValue;
+ if (skip(ctx, command) || ctx.isInTxScope()) return returnValue;
Map<Object, Object> map = command.getMap();
for (Object key : map.keySet()) {
@@ -233,11 +229,7 @@
return returnValue;
}
- private boolean inTransaction() throws SystemException {
- return txMgr != null && txMgr.getTransaction() != null;
- }
-
- private void prepareCacheLoader(InvocationContext ctx, GlobalTransaction gtx, TransactionContext transactionContext, boolean onePhase) throws Throwable {
+ private void prepareCacheLoader(TxInvocationContext ctx, GlobalTransaction gtx, TxInvocationContext transactionContext, boolean onePhase) throws Throwable {
if (transactionContext == null) {
throw new Exception("transactionContext for transaction " + gtx + " not found in transaction table");
}
@@ -253,7 +245,7 @@
log.trace("Converted method calls to cache loader modifications. List size: {0}", numMods);
if (numMods > 0) {
- Transaction tx = transactionContext.getTransaction();
+ Transaction tx = transactionContext.getRunningTransaction();
store.prepare(modsBuilder.modifications, tx, onePhase);
preparingTxs.put(tx, modsBuilder.affectedKeys);
Modified: trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -30,13 +30,10 @@
import org.infinispan.commands.write.ClearCommand;
import org.infinispan.commands.write.PutKeyValueCommand;
import org.infinispan.commands.write.RemoveCommand;
-import org.infinispan.commands.write.WriteCommand;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.transaction.GlobalTransaction;
-import javax.transaction.Transaction;
-
/**
* Always at the end of the chain, directly in front of the cache. Simply calls into the cache using reflection. If the
* call resulted in a modification, add the Modification to the end of the modification list keyed by the current
@@ -47,19 +44,19 @@
*/
public class CallInterceptor extends CommandInterceptor {
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
if (trace) log.trace("Suppressing invocation of method handlePrepareCommand.");
return null;
}
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
if (trace) log.trace("Suppressing invocation of method handleCommitCommand.");
return null;
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
if (trace) log.trace("Suppressing invocation of method handleRollbackCommand.");
return null;
}
@@ -76,9 +73,11 @@
retval = command.perform(ctx);
}
catch (Throwable t) {
- Transaction tx = ctx.getTransaction();
- if (ctx.isValidTransaction()) {
- tx.setRollbackOnly();
+ if (ctx.isInTxScope()) {
+ TxInvocationContext txContext = (TxInvocationContext) ctx;
+ if (txContext.isValidRunningTx()) {
+ txContext.getRunningTransaction().setRollbackOnly();
+ }
}
throw t;
}
@@ -87,32 +86,16 @@
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
- return handleAlterCacheMethod(ctx, command);
+ return invokeCommand(ctx, command);
}
@Override
public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
- return handleAlterCacheMethod(ctx, command);
+ return invokeCommand(ctx, command);
}
@Override
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
- return handleAlterCacheMethod(ctx, command);
+ return invokeCommand(ctx, command);
}
-
- private Object handleAlterCacheMethod(InvocationContext ctx, WriteCommand command)
- throws Throwable {
- Object result = invokeCommand(ctx, command);
- if (ctx.isValidTransaction()) {
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- if (gtx == null) {
- if (log.isDebugEnabled()) {
- log.debug("didn't find GlobalTransaction for " + ctx.getTransaction() + "; won't add modification to transaction list");
- }
- } else {
- ctx.getTransactionContext().addModification(command);
- }
- }
- return result;
- }
}
\ No newline at end of file
Modified: trunk/core/src/main/java/org/infinispan/interceptors/DistTxInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/DistTxInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/DistTxInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -2,6 +2,7 @@
import org.infinispan.commands.AbstractVisitor;
import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.CommandsFactory;
import org.infinispan.commands.write.DataWriteCommand;
import org.infinispan.commands.write.PutKeyValueCommand;
import org.infinispan.commands.write.PutMapCommand;
@@ -22,12 +23,15 @@
* @since 4.0
*/
public class DistTxInterceptor extends TxInterceptor {
+
DistributionManager dm;
ReplayCommandVisitor replayCommandVisitor = new ReplayCommandVisitor();
+ private CommandsFactory commandsFactory;
@Inject
- public void injectDistributionManager(DistributionManager dm) {
+ public void injectDistributionManager(DistributionManager dm, CommandsFactory commandsFactory) {
this.dm = dm;
+ this.commandsFactory = commandsFactory;
}
/**
Modified: trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -16,7 +16,7 @@
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.distribution.DistributionManager;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
@@ -136,8 +136,7 @@
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
- return handleWriteCommand(ctx, command,
- new SingleKeyRecipientGenerator(command.getKey()));
+ return handleWriteCommand(ctx, command, new SingleKeyRecipientGenerator(command.getKey()));
}
@Override
@@ -166,46 +165,34 @@
// ---- TX boundard commands
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
- if (!skipReplicationOfTransactionMethod(ctx)) {
- List<Address> recipients = new ArrayList<Address>(ctx.getTransactionContext().getTransactionParticipants());
- replicateCall(ctx, recipients, command, configuration.isSyncCommitPhase(), true);
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
+ if (ctx.isOriginLocal()) {
+ List<Address> recipients = new ArrayList<Address>(ctx.getTransactionParticipants());
+ rpcManager.multicastRpcCommand(recipients, command, configuration.isSyncCommitPhase(), true);
}
return invokeNextInterceptor(ctx, command);
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
Object retVal = invokeNextInterceptor(ctx, command);
- TransactionContext transactionContext = ctx.getTransactionContext();
- if (transactionContext.hasLocalModifications()) {
- PrepareCommand replicablePrepareCommand = command.copy(); // make sure we remove any "local" transactions
- replicablePrepareCommand.removeModifications(transactionContext.getLocalModifications());
- command = replicablePrepareCommand;
- }
boolean sync = isSynchronous(ctx);
- if (!skipReplicationOfTransactionMethod(ctx)) {
- if (trace) {
- log.trace("[" + rpcManager.getTransport().getAddress() + "] Running remote prepare for global tx {1}. Synchronous? {2}",
- rpcManager.getTransport().getAddress(), command.getGlobalTransaction(), sync);
- }
-
- List<Address> recipients = new ArrayList<Address>(ctx.getTransactionContext().getTransactionParticipants());
-
+ if (ctx.isOriginLocal()) {
+ List<Address> recipients = new ArrayList<Address>(ctx.getTransactionParticipants());
+ if (trace) log.trace("Multicasting PrepareCommand to recipients : " + recipients);
// this method will return immediately if we're the only member (because exclude_self=true)
- replicateCall(ctx, recipients, command, sync, false);
+ rpcManager.multicastRpcCommand(recipients, command, sync, false);
}
-
return retVal;
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
- if (!skipReplicationOfTransactionMethod(ctx) && !ctx.isLocalRollbackOnly()) {
- List<Address> recipients = new ArrayList<Address>(ctx.getTransactionContext().getTransactionParticipants());
- replicateCall(ctx, recipients, command, configuration.isSyncRollbackPhase(), true);
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
+ if (ctx.isOriginLocal()) {
+ List<Address> recipients = new ArrayList<Address>(ctx.getTransactionParticipants());
+ rpcManager.multicastRpcCommand(recipients, command, configuration.isSyncRollbackPhase(), true);
}
return invokeNextInterceptor(ctx, command);
}
@@ -215,7 +202,7 @@
// a) unsafeUnreliableReturnValues is false
// b) unsafeUnreliableReturnValues is true, we are in a TX and the command is conditional
- if (isNeedReliableReturnValues(ctx) || (isConditionalCommand && ctx.getTransaction() != null)) {
+ if (isNeedReliableReturnValues(ctx) || (isConditionalCommand && ctx.isInTxScope())) {
for (Object k : keys) remoteGetAndStoreInL1(ctx, k);
}
}
@@ -229,34 +216,33 @@
* time. If the operation didn't originate locally we won't do any replication either.
*/
private Object handleWriteCommand(InvocationContext ctx, WriteCommand command, RecipientGenerator recipientGenerator) throws Throwable {
- boolean local = isLocalModeForced(ctx);
+ boolean localModeForced = isLocalModeForced(ctx);
// see if we need to load values from remote srcs first
remoteGetBeforeWrite(ctx, command.isConditional(), recipientGenerator.getKeys());
// if this is local mode then skip distributing
- if (local && ctx.getTransaction() == null) return invokeNextInterceptor(ctx, command);
+ if (localModeForced && ctx.isInTxScope()) return invokeNextInterceptor(ctx, command);
// FIRST pass this call up the chain. Only if it succeeds (no exceptions) locally do we attempt to distribute.
Object returnValue = invokeNextInterceptor(ctx, command);
if (command.isSuccessful()) {
- if (ctx.getTransaction() == null) {
+ if (!ctx.isInTxScope()) {
if (ctx.isOriginLocal()) {
List<Address> rec = recipientGenerator.generateRecipients();
if (trace) log.trace("Invoking command {0} on hosts {1}", command, rec);
// if L1 caching is used make sure we broadcast an invalidate message
if (isL1CacheEnabled && rec != null) {
InvalidateCommand ic = cf.buildInvalidateFromL1Command(recipientGenerator.getKeys());
- replicateCall(ctx, ic, isSynchronous(ctx), false);
+ rpcManager.broadcastReplicableCommand(ic, isSynchronous(ctx));
}
- replicateCall(ctx, rec, command, isSynchronous(ctx), false);
+ rpcManager.multicastReplicableCommand(rec, command, isSynchronous(ctx));
}
} else {
- if (local) {
- ctx.getTransactionContext().addLocalModification(command);
+ if (!localModeForced) {
+ ((TxInvocationContext)ctx).addTransactionParticipants(recipientGenerator.generateRecipients());
} else {
// add to list of participants
- ctx.getTransactionContext().addTransactionParticipants(recipientGenerator.generateRecipients());
}
}
}
Modified: trunk/core/src/main/java/org/infinispan/interceptors/InterceptorChain.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/InterceptorChain.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/InterceptorChain.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -24,7 +24,7 @@
import org.infinispan.CacheException;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.factories.scopes.Scope;
@@ -55,7 +55,7 @@
/**
* used for invoking commands on the chain
*/
- private InvocationContextContainer invocationContextContainer;
+ private InvocationContextContainer icc;
private static final Log log = LogFactory.getLog(InterceptorChain.class);
/**
@@ -66,8 +66,8 @@
}
@Inject
- public void initialize(InvocationContextContainer invocationContextContainer) {
- this.invocationContextContainer = invocationContextContainer;
+ public void initialize(InvocationContextContainer icc) {
+ this.icc = icc;
}
@Start
@@ -248,26 +248,6 @@
}
/**
- * Similar to {@link #invoke(InvocationContext , VisitableCommand)}, but constructs a invocation context on the fly,
- * using {@link org.infinispan.context.InvocationContextContainer#get()}
- */
- public Object invokeRemote(VisitableCommand cacheCommand) throws Throwable {
- InvocationContext ctxt = invocationContextContainer.get();
- ctxt.setOriginLocal(false);
- return cacheCommand.acceptVisitor(ctxt, firstInChain);
- }
-
- /**
- * Similar to {@link #invoke(InvocationContext , VisitableCommand)}, but constructs a invocation context on the fly,
- * using {@link org.infinispan.context.InvocationContextContainer#get()} and setting the origin local flag to its
- * default value.
- */
- public Object invoke(VisitableCommand cacheCommand) throws Throwable {
- InvocationContext ctxt = invocationContextContainer.get();
- return cacheCommand.acceptVisitor(ctxt, firstInChain);
- }
-
- /**
* @return the first interceptor in the chain.
*/
public CommandInterceptor getFirstInChain() {
@@ -283,10 +263,6 @@
this.firstInChain = interceptor;
}
- public InvocationContext getInvocationContext() {
- return invocationContextContainer.get();
- }
-
/**
* Returns all interceptors which extend the given command interceptor.
*/
Modified: trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -26,7 +26,6 @@
import org.infinispan.commands.VisitableCommand;
import org.infinispan.commands.tx.PrepareCommand;
import org.infinispan.commands.write.ClearCommand;
-import org.infinispan.commands.write.DataWriteCommand;
import org.infinispan.commands.write.InvalidateCommand;
import org.infinispan.commands.write.PutKeyValueCommand;
import org.infinispan.commands.write.PutMapCommand;
@@ -34,14 +33,13 @@
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.interceptors.base.BaseRpcInterceptor;
import org.infinispan.jmx.annotations.ManagedAttribute;
import org.infinispan.jmx.annotations.ManagedOperation;
-import org.infinispan.transaction.GlobalTransaction;
-import org.infinispan.transaction.TransactionTable;
+import org.infinispan.transaction.xa.GlobalTransaction;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
@@ -82,24 +80,24 @@
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
- return handleInvalidate(ctx, command);
+ return handleInvalidate(ctx, command, command.getKey());
}
@Override
public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
- return handleInvalidate(ctx, command);
+ return handleInvalidate(ctx, command, command.getKey());
}
@Override
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
- return handleInvalidate(ctx, command);
+ return handleInvalidate(ctx, command, command.getKey());
}
@Override
public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
// just broadcast the clear command - this is simplest!
Object retval = invokeNextInterceptor(ctx, command);
- if (ctx.isOriginLocal()) replicateCall(ctx, command, defaultSynchronous);
+ if (ctx.isOriginLocal()) rpcManager.broadcastReplicableCommand(command, defaultSynchronous);
return retval;
}
@@ -110,58 +108,33 @@
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
Object retval = invokeNextInterceptor(ctx, command);
- Transaction tx = ctx.getTransaction();
- if (tx != null) {
- if (trace) log.trace("Entering InvalidationInterceptor's prepare phase");
- // fetch the modifications before the transaction is committed (and thus removed from the txTable)
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- TransactionContext transactionContext = ctx.getTransactionContext();
- if (transactionContext == null)
- throw new IllegalStateException("cannot find transaction transactionContext for " + gtx);
-
- if (transactionContext.hasModifications()) {
- List<WriteCommand> mods;
- if (transactionContext.hasLocalModifications()) {
- mods = Arrays.asList(command.getModifications());
- mods.removeAll(transactionContext.getLocalModifications());
- } else {
- mods = Arrays.asList(command.getModifications());
- }
- broadcastInvalidate(mods, tx, ctx);
- } else {
- if (trace) log.trace("Nothing to invalidate - no modifications in the transaction.");
- }
+ if (trace) log.trace("Entering InvalidationInterceptor's prepare phase");
+ // fetch the modifications before the transaction is committed (and thus removed from the txTable)
+ if (ctx.hasModifications() && ctx.isOriginLocal()) {
+ List<WriteCommand> mods = Arrays.asList(command.getModifications());
+ Transaction runningTransaction = ctx.getRunningTransaction();
+ if (runningTransaction == null) throw new IllegalStateException("we must have an associated transaction");
+ broadcastInvalidate(mods, runningTransaction, ctx);
+ } else {
+ if (trace) log.trace("Nothing to invalidate - no modifications in the transaction.");
}
return retval;
}
- private Object handleInvalidate(InvocationContext ctx, DataWriteCommand command) throws Throwable {
- return handleInvalidate(ctx, command, command.getKey());
- }
-
private Object handleInvalidate(InvocationContext ctx, WriteCommand command, Object... keys) throws Throwable {
Object retval = invokeNextInterceptor(ctx, command);
- if (command.isSuccessful()) {
- Transaction tx = ctx.getTransaction();
- if (log.isDebugEnabled()) log.debug("Is a CRUD method");
+ if (command.isSuccessful() && !ctx.isInTxScope()) {
if (keys != null && keys.length != 0) {
- // could be potentially TRANSACTIONAL. Ignore if it is, until we see a prepare().
- if (tx == null || !TransactionTable.isValid(tx)) {
- // the no-tx case:
- //replicate an evict call.
- invalidateAcrossCluster(isSynchronous(ctx), ctx, keys);
- } else {
- if (isLocalModeForced(ctx)) ctx.getTransactionContext().addLocalModification(command);
- }
+ invalidateAcrossCluster(isSynchronous(ctx), ctx, keys);
}
}
return retval;
}
private void broadcastInvalidate(List<WriteCommand> modifications, Transaction tx, InvocationContext ctx) throws Throwable {
- if (ctx.getTransaction() != null && !isLocalModeForced(ctx)) {
+ if (ctx.isInTxScope() && !isLocalModeForced(ctx)) {
if (modifications == null || modifications.isEmpty()) return;
InvalidationFilterVisitor filterVisitor = new InvalidationFilterVisitor(modifications.size());
filterVisitor.visitCollection(null, modifications);
@@ -217,9 +190,9 @@
incrementInvalidations();
InvalidateCommand command = commandsFactory.buildInvalidateCommand(keys);
if (log.isDebugEnabled())
- log.debug("Cache [" + rpcManager.getTransport().getAddress() + "] replicating " + command);
+ log.debug("Cache [" + rpcManager.getLocalAddress() + "] replicating " + command);
// voila, invalidated!
- replicateCall(ctx, command, synchronous);
+ rpcManager.broadcastReplicableCommand(command, synchronous);
}
}
Modified: trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -33,177 +33,79 @@
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.remoting.RpcManager;
-import org.infinispan.transaction.GlobalTransaction;
-import org.infinispan.transaction.TransactionTable;
+import org.infinispan.context.impl.TxInvocationContext;
+import org.infinispan.interceptors.base.CommandInterceptor;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
+public class InvocationContextInterceptor extends CommandInterceptor {
-public class InvocationContextInterceptor extends BaseTransactionalContextInterceptor {
- private RpcManager rpcManager;
-
- @Inject
- public void setDependencies(RpcManager rpcManager) {
- this.rpcManager = rpcManager;
- }
-
@Override
public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
- return handleAll(ctx, command, ctx.getGlobalTransaction(), false);
+ return handleAll(ctx, command);
}
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
- return handleAll(ctx, command, ctx.getGlobalTransaction(), true);
+ return handleAll(ctx, command);
}
@Override
public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
- return handleAll(ctx, command, ctx.getGlobalTransaction(), false);
+ return handleAll(ctx, command);
}
@Override
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
- return handleAll(ctx, command, ctx.getGlobalTransaction(), false);
+ return handleAll(ctx, command);
}
@Override
public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
- return handleAll(ctx, command, ctx.getGlobalTransaction(), false);
+ return handleAll(ctx, command);
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
- return handleAll(ctx, command, command.getGlobalTransaction(), true);
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
+ return handleAll(ctx, command);
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
- return handleAll(ctx, command, command.getGlobalTransaction(), true);
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
+ return handleAll(ctx, command);
}
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
- return handleAll(ctx, command, command.getGlobalTransaction(), true);
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
+ return handleAll(ctx, command);
}
@Override
public Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
- return handleAll(ctx, command, null, true);
+ return handleAll(ctx, command);
}
- private Object handleAll(InvocationContext ctx, VisitableCommand command, GlobalTransaction gtx, boolean scrubContextOnCompletion) throws Throwable {
+ private Object handleAll(InvocationContext ctx, VisitableCommand command) throws Throwable {
boolean suppressExceptions = false;
- Transaction suspendedTransaction = null;
- boolean resumeSuspended = false;
if (trace) log.trace("Invoked with command " + command + " and InvocationContext [" + ctx + "]");
+ if (ctx == null) throw new IllegalStateException("Null context not allowed!!");
- try {
- if (txManager != null) {
- Transaction tx = getTransaction();
- GlobalTransaction realGtx = getGlobalTransaction(tx, gtx);
- if (tx == null && realGtx != null && realGtx.isRemote()) tx = txTable.getLocalTransaction(gtx);
- setTransactionalContext(tx, realGtx, null, ctx);
- } else {
- setTransactionalContext(null, null, null, ctx);
- }
-
- if (ctx.hasFlag(Flag.FAIL_SILENTLY)) {
- log.debug("FAIL_SILENTLY flag is present - suspending any ongoing transaction.");
- suppressExceptions = true;
- if (ctx.getTransaction() != null) {
- suspendedTransaction = txManager.suspend();
- setTransactionalContext(null, null, null, ctx);
- if (trace) log.trace("Suspending transaction " + suspendedTransaction);
- resumeSuspended = true;
- } else {
- if (trace) log.trace("No ongoing transaction to suspend");
- }
- }
-
- Object retval;
- try {
- return invokeNextInterceptor(ctx, command);
- }
- catch (Throwable th) {
- retval = th;
- // if fail silently return a null
- if (suppressExceptions) return null;
- Throwable t = (Throwable) retval;
- if (t instanceof RuntimeException && t.getCause() != null) {
- throw t.getCause();
- } else {
- throw t;
- }
- }
- // assume we're the first interceptor in the chain. Handle the exception-throwing.
+ if (ctx.hasFlag(Flag.FAIL_SILENTLY)) {
+ suppressExceptions = true;
}
- finally {
- // TODO: scope upgrading should happen transparently
- /*
- * we should scrub txs after every call to prevent race conditions
- * basically any other call coming in on the same thread and hijacking any running tx's
- * was highlighted in JBCACHE-606
- */
- if (scrubContextOnCompletion) setTransactionalContext(null, null, null, ctx);
- // clean up any invocation-scope flags set up
- if (trace) log.trace("Resetting invocation-scope flags");
- ctx.resetFlags();
-
- // if this is a prepare, opt prepare or
-
- if (resumeSuspended) {
- txManager.resume(suspendedTransaction);
+ try {
+ return invokeNextInterceptor(ctx, command);
+ }
+ catch (Throwable th) {
+ if (suppressExceptions) {
+ log.trace("Exception while executiong code, failing silently...", th);
+ return null;
} else {
- if (ctx.getTransaction() != null && (TransactionTable.isValid(ctx.getTransaction()))) {
- copyInvocationScopeFlagsToTxScope(ctx);
- }
+ log.error("Execution error: ", th);
}
-
- // TODO: Calling ctx.reset() here breaks stuff. Check whether this is just becuse UTs expect stuff in the ctx or whether this really breaks functionality.
-// ctx.reset();
- // instead, for now, just wipe contents of the looked up entries
- ctx.clearLookedUpEntries();
+ throw th;
+ } finally {
+ ctx.resetFlags();
}
}
-
- private GlobalTransaction getGlobalTransaction(Transaction tx, GlobalTransaction gtx) {
- if (gtx == null) gtx = txTable.getCurrentTransaction(tx, false);
- if (gtx != null) gtx.setRemote(isRemoteGlobalTx(gtx));
- return gtx;
- }
-
- private Transaction getTransaction() throws SystemException {
- // this creates a context if one did not exist.
- if (txManager == null) {
- if (trace) log.trace("no transaction manager configured, setting tx as null.");
- return null;
- } else {
- return txManager.getTransaction();
- }
- }
-
- /**
- * Tests if a global transaction originated from a different cache in the cluster
- *
- * @param gtx
- * @return true if the gtx is remote, false if it originated locally.
- */
- private boolean isRemoteGlobalTx(GlobalTransaction gtx) {
- return gtx != null && (gtx.getAddress() != null) && (!gtx.getAddress().equals(rpcManager.getTransport().getAddress()));
- }
-
- private void copyInvocationScopeFlagsToTxScope(InvocationContext ctx) {
- // notify the transaction tCtx that this override is in place.
- TransactionContext tCtx = ctx.getTransactionContext();
- if (tCtx != null) {
- if (ctx.hasFlag(Flag.CACHE_MODE_LOCAL)) tCtx.setFlags(Flag.CACHE_MODE_LOCAL);
- if (ctx.hasFlag(Flag.SKIP_CACHE_STATUS_CHECK)) tCtx.setFlags(Flag.SKIP_CACHE_STATUS_CHECK);
- }
- }
}
\ No newline at end of file
Modified: trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -37,6 +37,7 @@
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.factories.EntryFactory;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
@@ -76,29 +77,38 @@
}
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
try {
return invokeNextInterceptor(ctx, command);
} finally {
- transactionalCleanup(true, ctx);
+ if (ctx.isInTxScope()) {
+ cleanupLocks(ctx, ctx.getLockOwner(), true);
+ } else {
+ throw new IllegalStateException("Attempting to do a commit or rollback but there is no transactional context in scope. " + ctx);
+ }
}
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
try {
return invokeNextInterceptor(ctx, command);
} finally {
- transactionalCleanup(false, ctx);
+ if (ctx.isInTxScope()) {
+ cleanupLocks(ctx, ctx.getLockOwner(), false);
+ } else {
+ throw new IllegalStateException("Attempting to do a commit or rollback but there is no transactional context in scope. " + ctx);
+ }
}
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
try {
return invokeNextInterceptor(ctx, command);
} finally {
- if (command.isOnePhaseCommit()) transactionalCleanup(true, ctx);
+ if (command.isOnePhaseCommit())
+ cleanupLocks(ctx, ctx.getLockOwner(), true);
}
}
@@ -108,8 +118,7 @@
public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable {
try {
entryFactory.wrapEntryForReading(ctx, command.getKey());
- Object r = invokeNextInterceptor(ctx, command);
- return r;
+ return invokeNextInterceptor(ctx, command);
} finally {
doAfterCall(ctx);
}
@@ -133,7 +142,6 @@
// get a snapshot of all keys in the data container
for (Object key : dataContainer.keySet())
entryFactory.wrapEntryForWriting(ctx, key, false, false, false, false);
- ctx.setContainsModifications(true);
return invokeNextInterceptor(ctx, command);
} finally {
doAfterCall(ctx);
@@ -153,9 +161,7 @@
if (command.getKeys() != null) {
for (Object key : command.getKeys()) entryFactory.wrapEntryForWriting(ctx, key, false, true, false, false);
}
- Object o = invokeNextInterceptor(ctx, command);
- if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
- return o;
+ return invokeNextInterceptor(ctx, command);
} finally {
doAfterCall(ctx);
}
@@ -165,9 +171,7 @@
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
try {
entryFactory.wrapEntryForWriting(ctx, command.getKey(), true, false, false, false);
- Object o = invokeNextInterceptor(ctx, command);
- if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
- return o;
+ return invokeNextInterceptor(ctx, command);
} finally {
doAfterCall(ctx);
}
@@ -179,9 +183,7 @@
for (Object key : command.getMap().keySet()) {
entryFactory.wrapEntryForWriting(ctx, key, true, false, false, false);
}
- Object o = invokeNextInterceptor(ctx, command);
- if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
- return o;
+ return invokeNextInterceptor(ctx, command);
}
finally {
doAfterCall(ctx);
@@ -192,9 +194,7 @@
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
try {
entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false, true);
- Object o = invokeNextInterceptor(ctx, command);
- if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
- return o;
+ return invokeNextInterceptor(ctx, command);
}
finally {
doAfterCall(ctx);
@@ -205,9 +205,7 @@
public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
try {
entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false, false);
- Object o = invokeNextInterceptor(ctx, command);
- if (!ctx.isContainsModifications()) ctx.setContainsModifications(command.isSuccessful());
- return o;
+ return invokeNextInterceptor(ctx, command);
}
finally {
doAfterCall(ctx);
@@ -217,17 +215,13 @@
@SuppressWarnings("unchecked")
private void doAfterCall(InvocationContext ctx) {
// for non-transactional stuff.
- if (ctx.getTransactionContext() == null) {
- if (ctx.isContainsModifications() || ctx.isContainsLocks()) {
- cleanupLocks(ctx, Thread.currentThread(), true);
- } else {
- if (trace) log.trace("Nothing to do since there are no modifications in scope.");
- }
+ if (!ctx.isInTxScope()) {
+ cleanupLocks(ctx, ctx.getLockOwner(), true);
} else {
if (trace) log.trace("Transactional. Not cleaning up locks till the transaction ends.");
if (useReadCommitted) {
Map<Object, CacheEntry> lookedUpEntries = ctx.getLookedUpEntries();
- if (!lookedUpEntries.isEmpty()) {
+ if (lookedUpEntries != null && !lookedUpEntries.isEmpty()) {
// This should be a Set but we can use an ArrayList instead for efficiency since we know that the elements
// will always be unique as they are keys from a Map. Also, we know the maximum size so this ArrayList
// should never resize.
@@ -291,27 +285,10 @@
}
}
}
- ctx.setContainsModifications(false);
- ctx.setContainsLocks(false);
}
protected void commitEntry(InvocationContext ctx, CacheEntry entry) {
entry.commit(dataContainer);
}
- @SuppressWarnings("unchecked")
- private void transactionalCleanup(boolean commit, InvocationContext ctx) {
- if (ctx.getTransactionContext() != null) {
- if (ctx.isContainsModifications() || ctx.isContainsLocks()) {
- if (trace)
- log.trace("Performing cleanup. Contains mods? {0} Contains locks? {1}", ctx.isContainsModifications(), ctx.isContainsLocks());
- cleanupLocks(ctx, ctx.getGlobalTransaction(), commit);
- } else {
- if (trace)
- log.trace("At transaction boundary (" + (commit ? "commit" : "rollback") + "), and we have no locks in context!");
- }
- } else {
- throw new IllegalStateException("Attempting to do a commit or rollback but there is no transactional context in scope. " + ctx);
- }
- }
}
Modified: trunk/core/src/main/java/org/infinispan/interceptors/NotificationInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/NotificationInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/NotificationInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -24,9 +24,10 @@
import org.infinispan.commands.tx.CommitCommand;
import org.infinispan.commands.tx.PrepareCommand;
import org.infinispan.commands.tx.RollbackCommand;
-import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.notifications.cachelistener.CacheNotifier;
+import org.infinispan.interceptors.base.CommandInterceptor;
/**
* The interceptor in charge of firing off notifications to cache listeners
@@ -34,7 +35,7 @@
* @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
* @since 4.0
*/
-public class NotificationInterceptor extends BaseTransactionalContextInterceptor {
+public class NotificationInterceptor extends CommandInterceptor {
private CacheNotifier notifier;
@Inject
@@ -43,24 +44,23 @@
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
Object retval = invokeNextInterceptor(ctx, command);
- if (command.isOnePhaseCommit()) notifier.notifyTransactionCompleted(ctx.getTransaction(), true, ctx);
-
+ if (command.isOnePhaseCommit()) notifier.notifyTransactionCompleted(ctx.getClusterTransactionId(), true, ctx);
return retval;
}
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
Object retval = invokeNextInterceptor(ctx, command);
- notifier.notifyTransactionCompleted(ctx.getTransaction(), true, ctx);
+ notifier.notifyTransactionCompleted(ctx.getClusterTransactionId(), true, ctx);
return retval;
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
Object retval = invokeNextInterceptor(ctx, command);
- notifier.notifyTransactionCompleted(ctx.getTransaction(), false, ctx);
+ notifier.notifyTransactionCompleted(ctx.getClusterTransactionId(), false, ctx);
return retval;
}
}
Modified: trunk/core/src/main/java/org/infinispan/interceptors/ReplicationInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/ReplicationInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/ReplicationInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -32,9 +32,8 @@
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.config.Configuration;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.interceptors.base.BaseRpcInterceptor;
-import org.infinispan.transaction.GlobalTransaction;
/**
* Takes care of replicating modifications to other caches in a cluster. Also listens for prepare(), commit() and
@@ -46,30 +45,28 @@
public class ReplicationInterceptor extends BaseRpcInterceptor {
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
- if (!skipReplicationOfTransactionMethod(ctx))
- replicateCall(ctx, command, configuration.isSyncCommitPhase(), true);
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
+ if (!ctx.isInTxScope()) throw new IllegalStateException("This should not be possible!");
+ if (ctx.isOriginLocal()) {
+ rpcManager.broadcastRpcCommand(command, configuration.isSyncCommitPhase(), true);
+ }
return invokeNextInterceptor(ctx, command);
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
Object retVal = invokeNextInterceptor(ctx, command);
- TransactionContext transactionContext = ctx.getTransactionContext();
- if (transactionContext.hasLocalModifications()) {
- PrepareCommand replicablePrepareCommand = command.copy(); // make sure we remove any "local" transactions
- replicablePrepareCommand.removeModifications(transactionContext.getLocalModifications());
- command = replicablePrepareCommand;
+ if (ctx.isOriginLocal() && command.hasModifications()) {
+ boolean async = configuration.getCacheMode() == Configuration.CacheMode.REPL_ASYNC;
+ rpcManager.broadcastRpcCommand(command, !async, false);
}
-
- if (!skipReplicationOfTransactionMethod(ctx)) runPreparePhase(command, command.getGlobalTransaction(), ctx);
return retVal;
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
- if (!skipReplicationOfTransactionMethod(ctx) && !ctx.isLocalRollbackOnly()) {
- replicateCall(ctx, command, configuration.isSyncRollbackPhase());
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
+ if (ctx.isOriginLocal() && !configuration.isOnePhaseCommit()) {
+ rpcManager.broadcastRpcCommand(command, configuration.isSyncRollbackPhase(), true);
}
return invokeNextInterceptor(ctx, command);
}
@@ -104,44 +101,11 @@
* time. If the operation didn't originate locally we won't do any replication either.
*/
private Object handleCrudMethod(InvocationContext ctx, WriteCommand command) throws Throwable {
- boolean local = isLocalModeForced(ctx);
- if (local && ctx.getTransaction() == null) return invokeNextInterceptor(ctx, command);
// FIRST pass this call up the chain. Only if it succeeds (no exceptions) locally do we attempt to replicate.
Object returnValue = invokeNextInterceptor(ctx, command);
-
- if (command.isSuccessful()) {
- if (ctx.getTransaction() == null && ctx.isOriginLocal()) {
- if (trace) {
- log.trace("invoking method " + command.getClass().getSimpleName() + ", members=" + rpcManager.getTransport().getMembers() + ", mode=" +
- configuration.getCacheMode() + ", exclude_self=" + true + ", timeout=" +
- configuration.getSyncReplTimeout());
- }
-
- replicateCall(ctx, command, isSynchronous(ctx));
- } else {
- if (local) ctx.getTransactionContext().addLocalModification(command);
- }
+ if (!isLocalModeForced(ctx) && command.isSuccessful() && ctx.isOriginLocal() && !ctx.isInTxScope()) {
+ rpcManager.broadcastReplicableCommand(command, isSynchronous(ctx));
}
return returnValue;
}
-
- /**
- * Calls prepare(GlobalTransaction,List,Address,boolean)) in all members except self. Waits for all responses. If one
- * of the members failed to prepare, its return value will be an exception. If there is one exception we rethrow it.
- * This will mark the current transaction as rolled back, which will cause the afterCompletion(int) callback to have
- * a status of <tt>MARKED_ROLLBACK</tt>. When we get that call, we simply roll back the transaction.<br/> If
- * everything runs okay, the afterCompletion(int) callback will trigger the @link
- * #runCommitPhase(GlobalTransaction)). <br/>
- *
- * @throws Exception
- */
- protected void runPreparePhase(PrepareCommand prepareMethod, GlobalTransaction gtx, InvocationContext ctx) throws Throwable {
- boolean async = configuration.getCacheMode() == Configuration.CacheMode.REPL_ASYNC;
- if (trace) {
- log.trace("(" + rpcManager.getTransport().getAddress() + "): running remote prepare for global tx " + gtx + " with async mode=" + async);
- }
-
- // this method will return immediately if we're the only member (because exclude_self=true)
- replicateCall(ctx, prepareMethod, !async);
- }
}
Deleted: trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,928 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.interceptors;
-
-import org.infinispan.CacheException;
-import org.infinispan.commands.CommandsFactory;
-import org.infinispan.commands.ReplicableCommand;
-import org.infinispan.commands.VisitableCommand;
-import org.infinispan.commands.tx.CommitCommand;
-import org.infinispan.commands.tx.PrepareCommand;
-import org.infinispan.commands.tx.RollbackCommand;
-import org.infinispan.commands.write.WriteCommand;
-import org.infinispan.context.Flag;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
-import org.infinispan.context.TransactionContext;
-import org.infinispan.factories.ComponentRegistry;
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.factories.context.ContextFactory;
-import org.infinispan.jmx.annotations.ManagedAttribute;
-import org.infinispan.jmx.annotations.ManagedOperation;
-import org.infinispan.manager.CacheManager;
-import org.infinispan.notifications.cachelistener.CacheNotifier;
-import org.infinispan.remoting.ReplicationException;
-import org.infinispan.transaction.GlobalTransaction;
-import org.infinispan.transaction.TransactionLog;
-import org.infinispan.transaction.TransactionTable;
-import org.infinispan.util.concurrent.ConcurrentHashSet;
-import org.infinispan.util.concurrent.locks.LockManager;
-
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * This interceptor is the new default at the head of all interceptor chains, and makes transactional attributes
- * available to all interceptors in the chain. This interceptor is also responsible for registering for synchronisation
- * on transaction completion.
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- * @author <a href="mailto:stevew at jofti.com">Steve Woodcock (stevew at jofti.com)</a>
- * @since 4.0
- */
-public class TxInterceptor extends BaseTransactionalContextInterceptor {
- protected CommandsFactory commandsFactory;
- private CacheNotifier notifier;
- private InvocationContextContainer invocationContextContainer;
- private ComponentRegistry componentRegistry;
- private ContextFactory contextFactory;
- private CacheManager cacheManager;
- private TransactionLog transactionLog;
-
- /**
- * List <Transaction>that we have registered for
- */
- private final Set<Transaction> transactions = new ConcurrentHashSet<Transaction>();
- private final Map<Transaction, GlobalTransaction> rollbackTransactions = new ConcurrentHashMap<Transaction, GlobalTransaction>(16);
- private final AtomicLong prepares = new AtomicLong(0);
- private final AtomicLong commits = new AtomicLong(0);
- private final AtomicLong rollbacks = new AtomicLong(0);
- private LockManager lockManager;
- private boolean statsEnabled;
-
- @Inject
- public void intialize(CacheManager cacheManager, ContextFactory contextFactory,
- CacheNotifier notifier, InvocationContextContainer icc,
- CommandsFactory factory, ComponentRegistry componentRegistry, LockManager lockManager,
- TransactionLog transactionLog) {
- this.contextFactory = contextFactory;
- this.commandsFactory = factory;
- this.cacheManager = cacheManager;
- this.notifier = notifier;
- this.invocationContextContainer = icc;
- this.componentRegistry = componentRegistry;
- this.lockManager = lockManager;
- this.transactionLog = transactionLog;
- setStatisticsEnabled(configuration.isExposeJmxStatistics());
- }
-
- @Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
- Object result = null;
-
- // this is a prepare, commit, or rollback.
- if (log.isDebugEnabled()) log.debug("Got gtx from invocation context " + ctx.getGlobalTransaction());
- try {
- if (ctx.getGlobalTransaction().isRemote()) {
- result = handleRemotePrepare(ctx, command);
- if (getStatisticsEnabled()) prepares.incrementAndGet();
- } else {
- if (trace) log.trace("received my own message (discarding it)");
- result = null;
- }
- }
- catch (Throwable e) {
- throwIfNeeded(ctx, e);
- }
-
- return result;
- }
-
- private void throwIfNeeded(InvocationContext ctx, Throwable throwable) throws Throwable {
- if (ctx.hasFlag(Flag.FAIL_SILENTLY))
- log.trace("There was a problem handling this request, but FAIL_SLIENTLY was set, so suppressing exception", throwable);
- else
- throw throwable;
- }
-
- @Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
- if (!ctx.getGlobalTransaction().isRemote()) {
- if (trace) log.trace("received my own message (discarding it)");
- return null;
- }
- try {
- if (trace) log.trace("(" + cacheManager.getAddress() + ") call on command [" + command + "]");
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- Transaction ltx = txTable.getLocalTransaction(gtx, true);
- // disconnect if we have a current tx associated
- Transaction currentTx = txManager.getTransaction();
- boolean resumeCurrentTxOnCompletion = false;
- try {
- if (!ltx.equals(currentTx)) {
- currentTx = txManager.suspend();
- resumeCurrentTxOnCompletion = true;
- txManager.resume(ltx);
- // make sure we set this in the ctx
- ctx.setTransaction(ltx);
- }
- if (log.isDebugEnabled()) log.debug(" executing commit() with local TX " + ltx + " under global tx " + gtx);
- txManager.commit();
- if (getStatisticsEnabled()) commits.incrementAndGet();
- }
- finally {
- //resume the old transaction if we suspended it
- if (resumeCurrentTxOnCompletion) {
- resumeTransactionOnCompletion(ctx, currentTx);
- }
- // remove from local lists.
- transactions.remove(ltx);
- // this tx has completed. Clean up in the tx table.
- txTable.cleanup(gtx);
- }
- if (log.isDebugEnabled()) log.debug("Finished remote rollback method for " + gtx);
- }
- catch (Throwable throwable) {
- throwIfNeeded(ctx, throwable);
- }
- return null;
- }
-
- @Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
- if (!ctx.getGlobalTransaction().isRemote()) {
- if (trace) log.trace("received my own message (discarding it)");
- return null;
- }
- try {
- if (trace) log.trace("(" + cacheManager.getAddress() + ") call on command [" + command + "]");
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- Transaction ltx = txTable.getLocalTransaction(gtx);
- if (ltx == null) {
- log.warn("No local transaction for this remotely originating rollback. Possibly rolling back before a prepare call was broadcast?");
- txTable.cleanup(gtx);
- return null;
- }
- // disconnect if we have a current tx associated
- Transaction currentTx = txManager.getTransaction();
- boolean resumeCurrentTxOnCompletion = false;
- try {
- if (!ltx.equals(currentTx)) {
- currentTx = txManager.suspend();
- resumeCurrentTxOnCompletion = true;
- txManager.resume(ltx);
- // make sure we set this in the ctx
- ctx.setTransaction(ltx);
- }
- if (log.isDebugEnabled()) log.debug("executing with local TX " + ltx + " under global tx " + gtx);
- txManager.rollback();
- if (getStatisticsEnabled()) rollbacks.incrementAndGet();
- }
- finally {
- //resume the old transaction if we suspended it
- if (resumeCurrentTxOnCompletion) {
- resumeTransactionOnCompletion(ctx, currentTx);
- }
-
- // remove from local lists.
- transactions.remove(ltx);
-
- // this tx has completed. Clean up in the tx table.
- txTable.cleanup(gtx);
- }
- if (log.isDebugEnabled()) log.debug("Finished remote commit/rollback method for " + gtx);
- }
- catch (Throwable throwable) {
- throwIfNeeded(ctx, throwable);
- }
-
- return null;
- }
-
- @Override
- public Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
- try {
- Object retval = attachGtxAndPassUpChain(ctx, command);
- // log non-transactional modification
- if (command instanceof WriteCommand && ctx.getTransaction() == null)
- transactionLog.logNoTxWrite((WriteCommand) command);
- return retval;
- }
- catch (Throwable throwable) {
- throwIfNeeded(ctx, throwable);
- return null;
- }
- }
-
- protected Object attachGtxAndPassUpChain(InvocationContext ctx, VisitableCommand command) throws Throwable {
- Transaction tx = ctx.getTransaction();
- if (tx != null) attachGlobalTransaction(ctx, tx, command);
- return invokeNextInterceptor(ctx, command);
- }
-
- // ------------------------------------------------------------------------
- // JMX statistics
- // ------------------------------------------------------------------------
-
- // --------------------------------------------------------------
-
- /**
- * Handles a remotely originating prepare call, by creating a local transaction for the remote global transaction and
- * replaying modifications in this new local transaction.
- *
- * @param ctx invocation context
- * @param command prepare command
- * @return result of the prepare, typically a null.
- * @throws Throwable in the event of problems.
- */
- private Object handleRemotePrepare(InvocationContext ctx, PrepareCommand command) throws Throwable {
- // the InvocationContextInterceptor would have set this for us
- GlobalTransaction gtx = ctx.getGlobalTransaction();
-
- // Is there a local transaction associated with GTX? (not the current tx associated with the thread, which may be
- // in the invocation context
- Transaction ltx = txTable.getLocalTransaction(gtx);
- Transaction currentTx = txManager.getTransaction();
- TransactionContext transactionContext;
- Object retval = null;
- boolean success = false;
- try {
- if (ltx == null) {
- if (currentTx != null) txManager.suspend();
- // create a new local transaction
- ltx = createLocalTx();
- if (log.isDebugEnabled()) log.debug("creating new tx transactionContext");
- transactionContext = contextFactory.createTransactionContext(ltx);
- // associate this with a global tx
- txTable.associateTransaction(ltx, gtx, transactionContext);
- if (trace) log.trace("Created new tx for gtx " + gtx);
-
- if (log.isDebugEnabled())
- log.debug("Started new local tx as result of remote prepare: local tx=" + ltx + " (status=" + ltx.getStatus() + "), gtx=" + gtx);
- } else {
- //this should be valid
- if (!TransactionTable.isValid(ltx))
- throw new CacheException("Transaction " + ltx + " not in correct state to be prepared");
-
- //associate this thread with the local transaction associated with the global transaction, IF the localTx is NOT the current tx.
- if (currentTx == null || !ltx.equals(currentTx)) {
- if (trace) log.trace("Suspending current tx " + currentTx);
- txManager.suspend();
- txManager.resume(ltx);
- }
-
- // Asssociate the local TX with the global TX. Create new
- // transactionContext for TX in txTable, the modifications
- // below will need this transactionContext to add their modifications
- // under the GlobalTx key
- transactionContext = txTable.getTransactionContext(gtx);
- if (transactionContext == null) {
- // create a new transaction transactionContext
- if (log.isDebugEnabled()) log.debug("creating new tx transactionContext");
- transactionContext = contextFactory.createTransactionContext(ltx);
- txTable.associateTransaction(ltx, gtx, transactionContext);
- }
- }
- if (trace) log.trace("Resuming existing tx " + ltx + ", global tx=" + gtx);
-
- // at this point we have a non-null ltx
-// setTransactionalContext(ltx, gtx, transactionContext, ctx);
- ctx.setTransactionContext(transactionContext);
- ctx.setTransaction(ltx);
- ctx.setGlobalTransaction(gtx);
-
- // register a sync handler for this tx.
- registerHandler(ltx, new RemoteSynchronizationHandler(gtx, ltx, transactionContext), ctx);
-
- success = false;
-
- // replay modifications
- replayModifications(ctx, ltx, command);
-
- success = true; // no exceptions were thrown above!!
-
- // now pass the prepare command up the chain as well.
- if (command.isOnePhaseCommit()) {
- if (trace)
- log.trace("Using one-phase prepare. Not propagating the prepare call up the stack until called to do so by the sync handler.");
- } else {
- // first log the transaction...
- transactionLog.logPrepare(command);
- // then pass up the prepare method itself.
- invokeNextInterceptor(ctx, command);
- }
- // JBCACHE-361 Confirm that the transaction is ACTIVE
- assertTxIsStillValid(ltx);
- }
- finally {
- // if we are running a one-phase commit, perform a commit or rollback now.
- if (trace) log.trace("Are we running a 1-phase commit? " + command.isOnePhaseCommit());
-
- if (command.isOnePhaseCommit()) {
- try {
- if (success) {
- ltx.commit();
- } else {
- ltx.rollback();
- }
- }
- catch (Throwable t) {
- log.error("Commit/rollback failed.", t);
- if (success) {
- // try another rollback...
- try {
- log.info("Attempting anotehr rollback");
- //invokeOnePhaseCommitMethod(globalTransaction, modifications.size() > 0, false);
- ltx.rollback();
- }
- catch (Throwable t2) {
- log.error("Unable to rollback", t2);
- }
- }
- }
- finally {
- transactions.remove(ltx);// JBAS-298
- }
- }
-
- txManager.suspend();// suspends ltx - could be null
- // resume whatever else we had going.
- if (currentTx != null) txManager.resume(currentTx);
- if (log.isDebugEnabled()) log.debug("Finished remote prepare " + gtx);
- }
-
- return retval;
- }
-
- private ReplicableCommand attachGlobalTransaction(InvocationContext ctx, Transaction tx, VisitableCommand command) throws Throwable {
- if (trace) {
- log.trace(" local transaction exists - registering global tx if not present for " + Thread.currentThread());
- }
- if (trace) {
- GlobalTransaction tempGtx = txTable.get(tx);
- log.trace("Associated gtx in txTable is " + tempGtx);
- }
-
- // register a sync handler for this tx - only if the globalTransaction is not remotely initiated.
- GlobalTransaction gtx = registerTransaction(tx, ctx);
- if (gtx == null) {
- // get the current globalTransaction from the txTable.
- gtx = txTable.get(tx);
- }
-
- // make sure we attach this globalTransaction to the invocation context.
- ctx.setGlobalTransaction(gtx);
-
- return command;
- }
-
- /**
- * Designed to be overridden. Returns a VisitableCommand fit for replaying locally, based on the modification passed
- * in. If a null value is returned, this means that the command should not be replayed.
- *
- * @param modification modification in a prepare call
- * @return a VisitableCommand representing this modification, fit for replaying, or null if the command should not be
- * replayed.
- */
- protected VisitableCommand getCommandToReplay(VisitableCommand modification) {
- return modification;
- }
-
- /**
- * Replays modifications
- */
- private void replayModifications(InvocationContext ctx, Transaction ltx, PrepareCommand command) throws Throwable {
- try {
- // replay modifications
- for (VisitableCommand modification : command.getModifications()) {
- VisitableCommand toReplay = getCommandToReplay(modification);
- if (toReplay != null) {
- invokeNextInterceptor(ctx, toReplay);
- assertTxIsStillValid(ltx);
- }
- }
- }
- catch (Throwable th) {
- log.error("prepare failed!", th);
- throw th;
- }
- }
-
- private void resumeTransactionOnCompletion(InvocationContext ctx, Transaction currentTx)
- throws SystemException, InvalidTransactionException {
- if (trace) log.trace("Resuming suspended transaction " + currentTx);
- txManager.suspend();
- if (currentTx != null) {
- txManager.resume(currentTx);
- ctx.setTransaction(currentTx);
- }
- }
-
- /**
- * Handles a commit or a rollback. Called by the synch handler. Simply tests that we are in the correct tx and
- * passes the meth call up the interceptor chain.
- *
- * @throws Throwable
- */
- private Object handleCommitRollback(InvocationContext ctx, VisitableCommand command) throws Throwable {
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- Object result;
- result = invokeNextInterceptor(ctx, command);
- if (log.isDebugEnabled()) log.debug("Finished local commit/rollback method for " + gtx);
- return result;
- }
-
- // --------------------------------------------------------------
- // Transaction phase runners
- // --------------------------------------------------------------
-
- protected PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, boolean onePhaseCommit) {
- return commandsFactory.buildPrepareCommand(gtx, modifications, cacheManager.getAddress(), onePhaseCommit);
- }
-
- /**
- * creates a commit()
- */
- protected void runCommitPhase(InvocationContext ctx, GlobalTransaction gtx, List<WriteCommand> modifications, boolean onePhaseCommit) {
- try {
- VisitableCommand commitCommand = onePhaseCommit ? buildPrepareCommand(gtx, modifications, true) : commandsFactory.buildCommitCommand(gtx);
-
- if (trace) log.trace("Running commit for " + gtx);
-
- handleCommitRollback(ctx, commitCommand);
- if (onePhaseCommit)
- transactionLog.logOnePhaseCommit(gtx, modifications);
- else
- transactionLog.logCommit(gtx);
- }
- catch (Throwable e) {
- log.warn("Commit failed. Clearing stale locks.");
- try {
- cleanupStaleLocks(ctx);
- }
- catch (RuntimeException re) {
- log.error("Unable to clear stale locks", re);
- throw re;
- }
- catch (Throwable e2) {
- log.error("Unable to clear stale locks", e2);
- throw new RuntimeException(e2);
- }
- if (e instanceof RuntimeException)
- throw (RuntimeException) e;
- else
- throw new RuntimeException("Commit failed.", e);
- }
- }
-
- protected void cleanupStaleLocks(InvocationContext ctx) throws Throwable {
- TransactionContext transactionContext = ctx.getTransactionContext();
- if (transactionContext != null) lockManager.unlock(ctx);
- }
-
- /**
- * creates a rollback()
- */
- protected void runRollbackPhase(InvocationContext ctx, GlobalTransaction gtx, Transaction tx) {
- try {
- // JBCACHE-457
- VisitableCommand rollbackCommand = commandsFactory.buildRollbackCommand(gtx);
- if (trace) log.trace(" running rollback for {0}", gtx);
- transactionLog.rollback(gtx);
-
- //JBCACHE-359 Store a lookup for the globalTransaction so a listener
- // callback can find it
- rollbackTransactions.put(tx, gtx);
-
- handleCommitRollback(ctx, rollbackCommand);
- }
- catch (Throwable e) {
- log.warn("Rollback had a problem", e);
- }
- finally {
- rollbackTransactions.remove(tx);
- }
- }
-
- private boolean isOnePhaseCommit() {
- if (!configuration.getCacheMode().isSynchronous()) {
- // this is a REPL_ASYNC call - do 1-phase commit. break!
- if (trace) log.trace("This is a REPL_ASYNC call (1 phase commit) - do nothing for beforeCompletion()");
- return true;
- }
- return false;
- }
-
- /**
- * Handles a local prepare - invoked by the sync handler. Tests if the current tx matches the gtx passed in to the
- * method call and passes the prepare() call up the chain.
- */
- public Object runPreparePhase(InvocationContext ctx, GlobalTransaction gtx, List<WriteCommand> modifications) throws Throwable {
- // running a 2-phase commit.
- PrepareCommand prepareCommand = buildPrepareCommand(gtx, modifications, false);
-
- transactionLog.logPrepare(prepareCommand);
-
- Object result;
-
- // Is there a local transaction associated with GTX ?
- Transaction ltx = ctx.getTransaction();
-
- //if ltx is not null and it is already running
- Transaction currentTransaction = txManager.getTransaction();
- if (currentTransaction != null && ltx != null && currentTransaction.equals(ltx)) {
- result = invokeNextInterceptor(ctx, prepareCommand);
- } else {
- log.warn("Local transaction does not exist or does not match expected transaction " + gtx);
- throw new CacheException(" local transaction " + ltx + " does not exist or does not match expected transaction " + gtx);
- }
- return result;
- }
-
- // --------------------------------------------------------------
- // Private helper methods
- // --------------------------------------------------------------
-
- protected void assertTxIsStillValid(Transaction tx) {
- if (!TransactionTable.isActive(tx)) {
- try {
- throw new ReplicationException("prepare() failed -- local transaction status is not STATUS_ACTIVE; is " + tx.getStatus());
- }
- catch (SystemException e) {
- throw new ReplicationException("prepare() failed -- local transaction status is not STATUS_ACTIVE; Unable to retrieve transaction status.");
- }
- }
- }
-
- /**
- * 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 (transactions.add(tx)) {
- gtx = txTable.getCurrentTransaction(tx, true);
- TransactionContext transactionContext;
- if (ctx.getGlobalTransaction() == null) {
- ctx.setGlobalTransaction(gtx);
- transactionContext = txTable.getTransactionContext(gtx);
- ctx.setTransactionContext(transactionContext);
- } else {
- transactionContext = ctx.getTransactionContext();
- }
- if (gtx.isRemote()) {
- // 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 {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 {0} is already registered and is rolling back.", tx);
- } else {
- if (trace) log.trace("Transaction {0} is already registered.", tx);
- }
- return gtx;
- }
-
- /**
- * Registers a sync hander against a tx.
- */
- private void registerHandler(Transaction tx, Synchronization sync, InvocationContext ctx) throws Exception {
- if (trace) log.trace("registering for TX completion: Synchronization (" + sync + ")");
- tx.registerSynchronization(sync);
- notifier.notifyTransactionRegistered(tx, ctx);
- }
-
- /**
- * Creates and starts a local tx
- *
- * @throws Exception
- */
- protected Transaction createLocalTx() throws Exception {
- if (trace) {
- log.trace("Creating transaction for thread " + Thread.currentThread());
- }
- Transaction localTx;
- if (txManager == null) throw new Exception("Failed to create local transaction; TransactionManager is null");
- txManager.begin();
- localTx = txManager.getTransaction();
- return localTx;
- }
-
- // ------------------------------------------------------------------------
- // Synchronization classes
- // ------------------------------------------------------------------------
-
- // this controls the whole transaction
-
- private class RemoteSynchronizationHandler implements Synchronization {
- Transaction tx = null;
- GlobalTransaction gtx = null;
- List<WriteCommand> modifications = null;
- TransactionContext transactionContext = null;
- protected InvocationContext ctx; // the context for this call.
-
- RemoteSynchronizationHandler(GlobalTransaction gtx, Transaction tx, TransactionContext entry) {
- this.gtx = gtx;
- this.tx = tx;
- this.transactionContext = entry;
- }
-
- public void beforeCompletion() {
- if (trace) log.trace("Running beforeCompletion on gtx " + gtx);
-
- if (transactionContext == null) {
- log.error("Transaction has a null transaction entry - beforeCompletion() will fail.");
- throw new IllegalStateException("cannot find transaction entry for " + gtx);
- }
-
- modifications = transactionContext.getModifications();
- ctx = invocationContextContainer.get();
- setTransactionalContext(tx, gtx, transactionContext, ctx);
-
- if (ctx.isFlagsUninitialized()) ctx.setFlags(transactionContext.getFlags());
-
- assertCanContinue();
-
- ctx.setOriginLocal(false);
- }
-
- // this should really not be done here -
- // it is supposed to be post commit not actually run the commit
- public void afterCompletion(int status) {
- // could happen if a rollback is called and beforeCompletion() doesn't get called.
- if (ctx == null) {
- ctx = invocationContextContainer.get();
- setTransactionalContext(tx, gtx, transactionContext, ctx);
-
- if (ctx.isFlagsUninitialized() && transactionContext != null) {
- // use the flags from the transaction entry instead
- ctx.setFlags(transactionContext.getFlags());
- }
- }
-
- try {
- assertCanContinue();
-
- try {
- if (txManager.getTransaction() != null && !txManager.getTransaction().equals(tx)) txManager.resume(tx);
- }
- catch (Exception e) {
- log.error("afterCompletion error: " + status, e);
- }
-
- if (trace) log.trace("calling aftercompletion for " + gtx);
-
- // set any transaction wide flags as current for this thread.
- if (transactionContext != null) {
- // this should ideally be set in beforeCompletion(), after compacting the list.
- if (modifications == null) modifications = transactionContext.getModifications();
- ctx.setFlags(transactionContext.getFlags());
- }
- if (tx != null) transactions.remove(tx);
-
- switch (status) {
- case Status.STATUS_COMMITTED:
- boolean onePhaseCommit = isOnePhaseCommit();
- if (log.isDebugEnabled()) log.debug("Running commit phase. One phase? " + onePhaseCommit);
- runCommitPhase(ctx, gtx, modifications, onePhaseCommit);
- log.debug("Finished commit phase");
- break;
- case Status.STATUS_UNKNOWN:
- log.warn("Received JTA STATUS_UNKNOWN in afterCompletion()! XA resources may not be in sync. The app should manually clean up resources at this point.");
- case Status.STATUS_MARKED_ROLLBACK:
- case Status.STATUS_ROLLEDBACK:
- log.debug("Running rollback phase");
- runRollbackPhase(ctx, gtx, tx);
- log.debug("Finished rollback phase");
- break;
-
- default:
- throw new IllegalStateException("illegal status: " + status);
- }
- }
- catch (Exception th) {
- log.trace("Caught exception ", th);
-
- }
- finally {
- // clean up the tx table
- txTable.cleanup(gtx);
- setTransactionalContext(null, null, null, ctx);
- cleanupInternalState();
- }
- }
-
- private void assertCanContinue() {
- if (!componentRegistry.invocationsAllowed(true) && !ctx.hasFlag(Flag.SKIP_CACHE_STATUS_CHECK))
- throw new IllegalStateException("Cache not in STARTED state!");
- }
-
- /**
- * Cleans out (nullifies) member variables held by the sync object for easier gc. Could be (falsely) seen as a
- * mem leak if the TM implementation hangs on to the synchronizations for an unnecessarily long time even after
- * the tx completes. See JBCACHE-1007.
- */
- private void cleanupInternalState() {
- tx = null;
- gtx = null;
- modifications = null;
- if (transactionContext != null) transactionContext.reset();
- transactionContext = null;
- }
-
- @Override
- public String toString() {
- return "TxInterceptor.RemoteSynchronizationHandler(gtx=" + gtx + ", tx=" + getTxAsString() + ")";
- }
-
- protected String getTxAsString() {
- // JBCACHE-1114 -- don't call toString() on tx or it can lead to stack overflow
- if (tx == null)
- return null;
-
- return tx.getClass().getName() + "@" + System.identityHashCode(tx);
- }
- }
-
- private class LocalSynchronizationHandler extends RemoteSynchronizationHandler {
- private boolean localRollbackOnly = true;
- // a VERY strange situation where a tx has remote origins, but since certain buddy group org methods perform local
- // cleanups even when remotely triggered, and optimistic locking is used, you end up with an implicit local tx.
- // This is STILL remotely originating though and this needs to be made explicit here.
- // this can be checked by inspecting the InvocationContext.isOriginLocal() at the time of registering the sync.
- private boolean remoteLocal = false;
- private Set<Flag> originalFlags, transactionalFlags;
-
- /**
- * A Synchronization for locally originating txs.
- * <p/>
- * a VERY strange situation where a tx has remote origins, but since certain buddy group org methods perform local
- * cleanups even when remotely triggered, and optimistic locking is used, you end up with an implicit local tx.
- * This is STILL remotely originating though and this needs to be made explicit here. this can be checked by
- * inspecting the InvocationContext.isOriginLocal() at the time of registering the sync.
- *
- * @param gtx
- * @param tx
- * @param remoteLocal
- */
- LocalSynchronizationHandler(GlobalTransaction gtx, Transaction tx, TransactionContext transactionContext, boolean remoteLocal) {
- super(gtx, tx, transactionContext);
- this.remoteLocal = remoteLocal;
- }
-
- @Override
- public void beforeCompletion() {
- super.beforeCompletion();
- ctx.setOriginLocal(!remoteLocal); // this is the LOCAL sync handler after all!
- // fetch the modifications before the transaction is committed
- // (and thus removed from the txTable)
- setTransactionalContext(tx, gtx, transactionContext, ctx);
- if (!transactionContext.hasModifications()) {
- if (trace) log.trace("No modifications in this tx. Skipping beforeCompletion()");
- modifications = Collections.emptyList();
- return;
- } else {
- modifications = transactionContext.getModifications();
- }
-
- // set any transaction wide flags as current for this thread, caching original flags that would then be reset
- originalFlags = ctx.getFlags();
- transactionalFlags = transactionContext.getFlags();
- ctx.setFlags(transactionalFlags);
-
- try {
- switch (tx.getStatus()) {
- // if we are active or preparing then we can go ahead
- case Status.STATUS_ACTIVE:
- case Status.STATUS_PREPARING:
- // run a prepare call.
-
- Object result = isOnePhaseCommit() ? null : runPreparePhase(ctx, gtx, modifications);
-
- if (result instanceof Throwable) {
- if (log.isDebugEnabled())
- log.debug("Transaction needs to be rolled back - the cache returned an instance of Throwable for this prepare call (tx=" + tx + " and gtx=" + gtx + ")", (Throwable) result);
- tx.setRollbackOnly();
- throw (Throwable) result;
- }
- break;
- default:
- throw new CacheException("transaction " + tx + " in status " + tx.getStatus() + " unable to start transaction");
- }
- }
- catch (Throwable t) {
- if (log.isWarnEnabled()) log.warn("Caught exception, will now set transaction to roll back", t);
- try {
- tx.setRollbackOnly();
- }
- catch (SystemException se) {
- throw new RuntimeException("setting tx rollback failed ", se);
- }
- if (t instanceof RuntimeException)
- throw (RuntimeException) t;
- else
- throw new RuntimeException("", t);
- }
- finally {
- localRollbackOnly = false;
- setTransactionalContext(null, null, null, ctx);
- ctx.setFlags(originalFlags);
- }
- }
-
- @Override
- public void afterCompletion(int status) {
- // could happen if a rollback is called and beforeCompletion() doesn't get called.
- if (ctx == null) ctx = invocationContextContainer.get();
- ctx.setLocalRollbackOnly(localRollbackOnly);
- setTransactionalContext(tx, gtx, transactionContext, ctx);
- if (transactionalFlags != null) ctx.setFlags(transactionalFlags);
- try {
- super.afterCompletion(status);
- }
- finally {
- ctx.setFlags(originalFlags);
- if (getStatisticsEnabled()) {
- if (status == Status.STATUS_ROLLEDBACK) rollbacks.incrementAndGet();
- else if (status == Status.STATUS_COMMITTED) commits.incrementAndGet();
- }
- }
- }
-
- @Override
- public String toString() {
- return "TxInterceptor.LocalSynchronizationHandler(gtx=" + gtx + ", tx=" + getTxAsString() + ")";
- }
- }
-
- @ManagedOperation
- public void resetStatistics() {
- prepares.set(0);
- commits.set(0);
- rollbacks.set(0);
- }
-
- @ManagedAttribute
- public boolean getStatisticsEnabled() {
- return this.statsEnabled;
- }
-
- @ManagedAttribute
- public void setStatisticsEnabled(boolean enabled) {
- this.statsEnabled = enabled;
- }
-
- @ManagedAttribute(description = "number of transaction prepares")
- public long getPrepares() {
- return prepares.get();
- }
-
- @ManagedAttribute(description = "number of transaction commits")
- public long getCommits() {
- return commits.get();
- }
-
- @ManagedAttribute(description = "number of transaction rollbacks")
- public long getRollbacks() {
- return rollbacks.get();
- }
-}
\ No newline at end of file
Added: trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,214 @@
+package org.infinispan.interceptors;
+
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.read.GetKeyValueCommand;
+import org.infinispan.commands.read.SizeCommand;
+import org.infinispan.commands.tx.CommitCommand;
+import org.infinispan.commands.tx.PrepareCommand;
+import org.infinispan.commands.tx.RollbackCommand;
+import org.infinispan.commands.write.ClearCommand;
+import org.infinispan.commands.write.EvictCommand;
+import org.infinispan.commands.write.InvalidateCommand;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.commands.write.PutMapCommand;
+import org.infinispan.commands.write.RemoveCommand;
+import org.infinispan.commands.write.ReplaceCommand;
+import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.context.Flag;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.InitiatorTxInvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.interceptors.base.CommandInterceptor;
+import org.infinispan.jmx.annotations.ManagedAttribute;
+import org.infinispan.jmx.annotations.ManagedOperation;
+import org.infinispan.transaction.TransactionLog;
+import org.infinispan.transaction.xa.TxEnlistingManager;
+import org.infinispan.transaction.xa.TransactionXaAdapter;
+
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public class TxInterceptor extends CommandInterceptor {
+
+ private TxEnlistingManager txEnlistingManager;
+ private TransactionLog transactionLog;
+
+ private final AtomicLong prepares = new AtomicLong(0);
+ private final AtomicLong commits = new AtomicLong(0);
+ private final AtomicLong rollbacks = new AtomicLong(0);
+ private boolean statsEnabled;
+
+
+ @Inject
+ public void init(TxEnlistingManager txEnlistingManager, TransactionLog transactionLog) {
+ this.txEnlistingManager = txEnlistingManager;
+ this.transactionLog = transactionLog;
+ setStatisticsEnabled(configuration.isExposeJmxStatistics());
+ }
+
+ @Override
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
+ if (!ctx.isOriginLocal()) {
+ // replay modifications
+ for (VisitableCommand modification : command.getModifications()) {
+ VisitableCommand toReplay = getCommandToReplay(modification);
+ if (toReplay != null) {
+ invokeNextInterceptor(ctx, toReplay);
+ }
+ }
+ }
+ if (!command.isOnePhaseCommit()) {
+ transactionLog.logPrepare(command);
+ } else {
+ transactionLog.logOnePhaseCommit(ctx.getClusterTransactionId(), Arrays.asList(command.getModifications()));
+ }
+ if (getStatisticsEnabled()) prepares.incrementAndGet();
+ return invokeNextInterceptor(ctx, command);
+ }
+
+ @Override
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
+ if (getStatisticsEnabled()) commits.incrementAndGet();
+ transactionLog.logCommit(command.getGlobalTransaction());
+ return invokeNextInterceptor(ctx, command);
+ }
+
+ @Override
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
+ if (getStatisticsEnabled()) rollbacks.incrementAndGet();
+ transactionLog.rollback(command.getGlobalTransaction());
+ return invokeNextInterceptor(ctx, command);
+ }
+
+ /**
+ * Designed to be overridden. Returns a VisitableCommand fit for replaying locally, based on the modification passed
+ * in. If a null value is returned, this means that the command should not be replayed.
+ *
+ * @param modification modification in a prepare call
+ * @return a VisitableCommand representing this modification, fit for replaying, or null if the command should not be
+ * replayed.
+ */
+ protected VisitableCommand getCommandToReplay(VisitableCommand modification) {
+ return modification;
+ }
+
+ @Override
+ public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
+ return enlistWriteAndInvokeNext(ctx, command);
+ }
+
+ @Override
+ public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
+ return enlistWriteAndInvokeNext(ctx, command);
+ }
+
+ @Override
+ public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
+ return enlistWriteAndInvokeNext(ctx, command);
+ }
+
+ @Override
+ public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
+ return enlistWriteAndInvokeNext(ctx, command);
+ }
+
+ @Override
+ public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
+ return enlistWriteAndInvokeNext(ctx, command);
+ }
+
+ @Override
+ public Object visitEvictCommand(InvocationContext ctx, EvictCommand command) throws Throwable {
+ return enlistWriteAndInvokeNext(ctx, command);
+ }
+
+ @Override
+ public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand invalidateCommand) throws Throwable {
+ return enlistWriteAndInvokeNext(ctx, invalidateCommand);
+ }
+
+ @Override
+ public Object visitSizeCommand(InvocationContext ctx, SizeCommand command) throws Throwable {
+ return enlistReadAndInvokeNext(ctx, command);
+ }
+
+ @Override
+ public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable {
+ return enlistReadAndInvokeNext(ctx, command);
+ }
+
+ private Object enlistReadAndInvokeNext(InvocationContext ctx, VisitableCommand command) throws Throwable {
+ if (shouldEnlist(ctx)) {
+ TransactionXaAdapter xaAdapter = txEnlistingManager.enlist(ctx);
+ InitiatorTxInvocationContext initiatorTxContext = (InitiatorTxInvocationContext) ctx;
+ initiatorTxContext.setXaCache(xaAdapter);
+ }
+ return invokeNextInterceptor(ctx, command);
+ }
+
+ private Object enlistWriteAndInvokeNext(InvocationContext ctx, WriteCommand command) throws Throwable {
+ if (shouldEnlist(ctx)) {
+ TransactionXaAdapter xaAdapter = txEnlistingManager.enlist(ctx);
+ InitiatorTxInvocationContext initiatorTxContext = (InitiatorTxInvocationContext) ctx;
+ if (!isLocalModeForced(ctx)) {
+ xaAdapter.addModification(command);
+ }
+ initiatorTxContext.setXaCache(xaAdapter);
+ }
+ if (!ctx.isInTxScope())
+ transactionLog.logNoTxWrite(command);
+ return invokeNextInterceptor(ctx, command);
+ }
+
+ private boolean shouldEnlist(InvocationContext ctx) {
+ return ctx.isInTxScope() & ctx.isOriginLocal();
+ }
+
+ private boolean isLocalModeForced(InvocationContext icx) {
+ if (icx.hasFlag(Flag.CACHE_MODE_LOCAL)) {
+ if (log.isDebugEnabled()) log.debug("LOCAL mode forced on invocation. Suppressing clustered events.");
+ return true;
+ }
+ return false;
+ }
+
+ @ManagedOperation
+ public void resetStatistics() {
+ prepares.set(0);
+ commits.set(0);
+ rollbacks.set(0);
+ }
+
+ @ManagedAttribute
+ public boolean getStatisticsEnabled() {
+ return this.statsEnabled;
+ }
+
+ @ManagedAttribute
+ public void setStatisticsEnabled(boolean enabled) {
+ this.statsEnabled = enabled;
+ }
+
+ @ManagedAttribute(description = "number of transaction prepares")
+ public long getPrepares() {
+ return prepares.get();
+ }
+
+ @ManagedAttribute(description = "number of transaction commits")
+ public long getCommits() {
+ return commits.get();
+ }
+
+ @ManagedAttribute(description = "number of transaction rollbacks")
+ public long getRollbacks() {
+ return rollbacks.get();
+ }
+}
Modified: trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,155 +21,34 @@
*/
package org.infinispan.interceptors.base;
-import org.infinispan.commands.CommandsFactory;
-import org.infinispan.commands.ReplicableCommand;
-import org.infinispan.commands.remote.CacheRpcCommand;
-import org.infinispan.commands.remote.SingleRpcCommand;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
-import org.infinispan.remoting.ReplicationQueue;
-import org.infinispan.remoting.ResponseMode;
-import org.infinispan.remoting.RpcManager;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
-import org.infinispan.transaction.TransactionTable;
+import org.infinispan.remoting.rpc.CacheRpcManager;
-import javax.transaction.Transaction;
-import java.util.List;
-
/**
* Acts as a base for all RPC calls - subclassed by
*
* @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ * @author Mircea.Markus at jboss.com
* @since 4.0
*/
public abstract class BaseRpcInterceptor extends CommandInterceptor {
- private ReplicationQueue replicationQueue;
- protected TransactionTable txTable;
- private CommandsFactory commandsFactory;
- protected RpcManager rpcManager;
- protected boolean defaultSynchronous;
- private boolean stateTransferEnabled;
+ protected CacheRpcManager rpcManager;
@Inject
- public void injectComponents(RpcManager rpcManager, ReplicationQueue replicationQueue,
- TransactionTable txTable, CommandsFactory commandsFactory) {
+ public void init(CacheRpcManager rpcManager) {
this.rpcManager = rpcManager;
- this.replicationQueue = replicationQueue;
- this.txTable = txTable;
- this.commandsFactory = commandsFactory;
}
+ protected boolean defaultSynchronous;
@Start
public void init() {
defaultSynchronous = configuration.getCacheMode().isSynchronous();
- stateTransferEnabled = configuration.isFetchInMemoryState();
}
- /**
- * Checks whether any of the responses are exceptions. If yes, re-throws them (as exceptions or runtime exceptions).
- */
- protected void checkResponses(List rsps) throws Throwable {
- if (rsps != null) {
- for (Object rsp : rsps) {
- if (rsp != null && rsp instanceof Throwable) {
- // lets print a stack trace first.
- if (log.isDebugEnabled())
- log.debug("Received Throwable from remote cache", (Throwable) rsp);
- throw (Throwable) rsp;
- }
- }
- }
- }
-
- protected void replicateCall(InvocationContext ctx, CacheRpcCommand call, boolean sync, boolean useOutOfBandMessage) throws Throwable {
- replicateCall(ctx, null, call, sync, useOutOfBandMessage);
- }
-
- protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync, boolean useOutOfBandMessage) throws Throwable {
- replicateCall(ctx, null, call, sync, useOutOfBandMessage);
- }
-
- protected void replicateCall(InvocationContext ctx, CacheRpcCommand call, boolean sync) throws Throwable {
- replicateCall(ctx, null, call, sync, false);
- }
-
- protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync) throws Throwable {
- replicateCall(ctx, null, call, sync, false);
- }
-
- protected void replicateCall(InvocationContext ctx, List<Address> recipients, ReplicableCommand c, boolean sync, boolean useOutOfBandMessage) throws Throwable {
- long syncReplTimeout = configuration.getSyncReplTimeout();
-
- if (ctx.hasFlag(Flag.FORCE_ASYNCHRONOUS)) sync = false;
- else if (ctx.hasFlag(Flag.FORCE_SYNCHRONOUS)) sync = true;
-
- // tx-level overrides are more important
- Transaction tx = ctx.getTransaction();
- if (tx != null) {
- TransactionContext transactionContext = ctx.getTransactionContext();
- if (transactionContext != null) {
- if (transactionContext.isForceAsyncReplication()) sync = false;
- else if (transactionContext.isForceSyncReplication()) sync = true;
- }
- }
-
- replicateCall(recipients, c, sync, useOutOfBandMessage, syncReplTimeout);
- }
-
- protected void replicateCall(List<Address> recipients, ReplicableCommand call, boolean sync, boolean useOutOfBandMessage, long timeout) throws Throwable {
- if (trace) log.trace("Broadcasting call " + call + " to recipient list " + recipients);
-
- if (!sync && replicationQueue != null) {
- if (log.isDebugEnabled()) log.debug("Putting call " + call + " on the replication queue.");
- replicationQueue.add(call);
- } else {
- List<Address> callRecipients = recipients;
- if (callRecipients == null) {
- callRecipients = null;
- if (trace)
- log.trace("Setting call recipients to " + callRecipients + " since the original list of recipients passed in is null.");
- }
- SingleRpcCommand command = commandsFactory.buildSingleRpcCommand(call);
-
- List rsps = rpcManager.invokeRemotely(callRecipients,
- command,
- sync ? ResponseMode.SYNCHRONOUS : ResponseMode.ASYNCHRONOUS, // is synchronised?
- timeout, useOutOfBandMessage, stateTransferEnabled
- );
- if (trace) log.trace("responses=" + rsps);
- if (sync) checkResponses(rsps);
- }
- }
-
- /**
- * It does not make sense replicating a transaction method(commit, rollback, prepare) if one of the following is
- * true:
- * <pre>
- * - call was not initiated here, but on other member of the cluster
- * - there is no transaction. Why broadcast a commit or rollback if there is no transaction going on?
- * - the current transaction did not modify any data
- * </pre>
- */
- protected final boolean skipReplicationOfTransactionMethod(InvocationContext ctx) {
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- return ctx.getTransaction() == null || gtx == null || gtx.isRemote() || ctx.hasFlag(Flag.CACHE_MODE_LOCAL)
- || !ctx.getTransactionContext().hasModifications();
- }
-
- /**
- * The call runs in a transaction and it was initiated on this cache instance of the cluster.
- */
- protected final boolean isTransactionalAndLocal(InvocationContext ctx) {
- GlobalTransaction gtx = ctx.getGlobalTransaction();
- boolean isInitiatedHere = gtx != null && !gtx.isRemote();
- return isInitiatedHere && (ctx.getTransaction() != null);
- }
-
protected final boolean isSynchronous(InvocationContext ctx) {
if (ctx.hasFlag(Flag.FORCE_SYNCHRONOUS))
return true;
Modified: trunk/core/src/main/java/org/infinispan/interceptors/base/PrePostProcessingCommandInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/base/PrePostProcessingCommandInterceptor.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/interceptors/base/PrePostProcessingCommandInterceptor.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -34,6 +34,7 @@
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
/**
* This interceptor adds pre and post processing to each <tt>visitXXX()</tt> method.
@@ -169,7 +170,7 @@
// tx commands
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
try {
return (doBeforeCall(ctx, command)) ? handlePrepareCommand(ctx, command) : null;
}
@@ -183,7 +184,7 @@
}
@Override
- public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
+ public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
try {
return (doBeforeCall(ctx, command)) ? handleRollbackCommand(ctx, command) : null;
}
@@ -197,7 +198,7 @@
}
@Override
- public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
+ public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand command) throws Throwable {
try {
return (doBeforeCall(ctx, command)) ? handleCommitCommand(ctx, command) : null;
}
Modified: trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -10,12 +10,12 @@
import org.infinispan.loaders.CacheLoaderConfig;
import org.infinispan.loaders.CacheLoaderException;
import org.infinispan.marshall.Marshaller;
-import org.infinispan.remoting.ResponseFilter;
-import org.infinispan.remoting.ResponseMode;
-import org.infinispan.remoting.RpcManager;
import org.infinispan.remoting.responses.ClusteredGetResponseValidityFilter;
import org.infinispan.remoting.responses.Response;
import org.infinispan.remoting.responses.SuccessfulResponse;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.remoting.transport.Address;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -91,7 +91,7 @@
}
private boolean isLocalCall() {
- InvocationContext invocationContext = cache.getInvocationContextContainer().get();
+ InvocationContext invocationContext = cache.getInvocationContextContainer().getThreadContext();
return invocationContext.isOriginLocal();
}
Modified: trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -38,7 +38,7 @@
import org.infinispan.lifecycle.ComponentStatus;
import org.infinispan.lifecycle.Lifecycle;
import org.infinispan.notifications.cachemanagerlistener.CacheManagerNotifier;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.remoting.transport.Address;
import java.io.IOException;
Modified: trunk/core/src/main/java/org/infinispan/marshall/MarshalledValue.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/MarshalledValue.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/MarshalledValue.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -24,7 +24,7 @@
import org.infinispan.CacheException;
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.jboss.util.stream.MarshalledValueInputStream;
import java.io.ByteArrayInputStream;
Modified: trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -45,7 +45,7 @@
import org.infinispan.remoting.responses.UnsuccessfulResponse;
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.transaction.TransactionLog;
import org.infinispan.util.FastCopyHashMap;
import org.infinispan.util.Immutables;
Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,7 +23,7 @@
import net.jcip.annotations.Immutable;
import org.infinispan.CacheException;
-import org.infinispan.atomic.AtomicHashMap;
+import org.infinispan.atomic.atomichashmap.AtomicHashMap;
import org.infinispan.commands.control.StateTransferControlCommand;
import org.infinispan.commands.read.GetKeyValueCommand;
import org.infinispan.commands.remote.ClusteredGetCommand;
@@ -45,13 +45,13 @@
import org.infinispan.container.entries.TransientMortalCacheEntry;
import org.infinispan.marshall.MarshalledValue;
import org.infinispan.marshall.jboss.externalizers.*;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.remoting.responses.ExceptionResponse;
import org.infinispan.remoting.responses.ExtendedResponse;
import org.infinispan.remoting.responses.SuccessfulResponse;
import org.infinispan.remoting.responses.UnsuccessfulResponse;
import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.FastCopyHashMap;
import org.infinispan.util.Util;
import org.jboss.marshalling.ClassExternalizerFactory;
Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -29,7 +29,7 @@
import org.infinispan.io.ByteBuffer;
import org.infinispan.io.ExposedByteArrayOutputStream;
import org.infinispan.marshall.AbstractMarshaller;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.util.Util;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,7 +23,7 @@
import net.jcip.annotations.Immutable;
import org.infinispan.CacheException;
-import org.infinispan.atomic.AtomicHashMap;
+import org.infinispan.atomic.atomichashmap.AtomicHashMap;
import org.infinispan.commands.control.StateTransferControlCommand;
import org.infinispan.commands.read.GetKeyValueCommand;
import org.infinispan.commands.remote.ClusteredGetCommand;
@@ -50,7 +50,7 @@
import org.infinispan.remoting.responses.SuccessfulResponse;
import org.infinispan.remoting.responses.UnsuccessfulResponse;
import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.FastCopyHashMap;
import org.infinispan.util.Util;
import org.jboss.marshalling.ClassTable;
Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,7 +23,7 @@
import net.jcip.annotations.Immutable;
import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.jboss.marshalling.Creator;
import org.jboss.marshalling.Externalizer;
Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -22,7 +22,7 @@
package org.infinispan.marshall.jboss.externalizers;
import org.infinispan.commands.control.StateTransferControlCommand;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import org.jboss.marshalling.Creator;
import java.io.IOException;
Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -24,7 +24,7 @@
import net.jcip.annotations.Immutable;
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.marshall.jboss.MarshallUtil;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.transaction.TransactionLog;
import org.jboss.marshalling.Creator;
import org.jboss.marshalling.Externalizer;
Modified: trunk/core/src/main/java/org/infinispan/notifications/Listener.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/notifications/Listener.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/notifications/Listener.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -39,7 +39,7 @@
* <h4>Transactional Semantics</h4> <p/> Since the event is delivered during the actual cache call, the transactional
* outcome is not yet known. For this reason, <i>events are always delivered, even if the changes they represent are
* discarded by their containing transaction</i>. For applications that must only process events that represent changes
- * in a completed transaction, {@link org.infinispan.notifications.cachelistener.event.TransactionalEvent#getTransaction()}
+ * in a completed transaction, {@link org.infinispan.notifications.cachelistener.event.TransactionalEvent#getGlobalTransaction()}
* can be used, along with {@link org.infinispan.notifications.cachelistener.event.TransactionCompletedEvent#isTransactionSuccessful()}
* to record events and later process them once the transaction has been successfully committed. Example 4 demonstrates
* this. </p> <p/> <h4>Threading Semantics</h4> <p/> A listener implementation must be capable of handling concurrent
Modified: trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifier.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifier.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifier.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -26,9 +26,8 @@
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.notifications.Listenable;
+import org.infinispan.transaction.xa.GlobalTransaction;
-import javax.transaction.Transaction;
-
/**
* Public interface with all allowed notifications.
*
@@ -89,12 +88,12 @@
* @param transaction the transaction that has just completed
* @param successful if true, the transaction committed. If false, this is a rollback event
*/
- void notifyTransactionCompleted(Transaction transaction, boolean successful, InvocationContext ctx);
+ void notifyTransactionCompleted(GlobalTransaction transaction, boolean successful, InvocationContext ctx);
/**
* Notifies all registered listeners of a transaction registration event.
*
- * @param transaction the transaction that has just completed
+ * @param globalTransaction
*/
- void notifyTransactionRegistered(Transaction transaction, InvocationContext ctx);
+ void notifyTransactionRegistered(GlobalTransaction globalTransaction, InvocationContext ctx);
}
\ No newline at end of file
Modified: trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifierImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifierImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/notifications/cachelistener/CacheNotifierImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,16 +23,17 @@
import org.infinispan.Cache;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.notifications.AbstractListenerImpl;
import org.infinispan.notifications.cachelistener.annotation.*;
import org.infinispan.notifications.cachelistener.event.*;
import static org.infinispan.notifications.cachelistener.event.Event.Type.*;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
-import javax.transaction.Transaction;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
@@ -43,6 +44,7 @@
* Helper class that handles all notifications to registered listeners.
*
* @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ * @author Mircea.Markus at jboss.com
* @since 4.0
*/
public class CacheNotifierImpl extends AbstractListenerImpl implements CacheNotifier {
@@ -112,201 +114,178 @@
public void notifyCacheEntryCreated(Object key, boolean pre, InvocationContext ctx) {
if (!cacheEntryCreatedListeners.isEmpty()) {
boolean originLocal = ctx.isOriginLocal();
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(originLocal);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_CREATED);
for (ListenerInvocation listener : cacheEntryCreatedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
public void notifyCacheEntryModified(Object key, Object value, boolean pre, InvocationContext ctx) {
if (!cacheEntryModifiedListeners.isEmpty()) {
boolean originLocal = ctx.isOriginLocal();
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(originLocal);
e.setValue(value);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_MODIFIED);
for (ListenerInvocation listener : cacheEntryModifiedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
public void notifyCacheEntryRemoved(Object key, Object value, boolean pre, InvocationContext ctx) {
if (!cacheEntryRemovedListeners.isEmpty()) {
boolean originLocal = ctx.isOriginLocal();
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(originLocal);
e.setValue(value);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_REMOVED);
for (ListenerInvocation listener : cacheEntryRemovedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
public void notifyCacheEntryVisited(Object key, boolean pre, InvocationContext ctx) {
if (!cacheEntryVisitedListeners.isEmpty()) {
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_VISITED);
for (ListenerInvocation listener : cacheEntryVisitedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
public void notifyCacheEntryEvicted(final Object key, final boolean pre, InvocationContext ctx) {
if (!cacheEntryEvictedListeners.isEmpty()) {
final boolean originLocal = ctx.isOriginLocal();
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(originLocal);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_EVICTED);
for (ListenerInvocation listener : cacheEntryEvictedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
public void notifyCacheEntryInvalidated(final Object key, final boolean pre, InvocationContext ctx) {
if (!cacheEntryInvalidatedListeners.isEmpty()) {
final boolean originLocal = ctx.isOriginLocal();
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(originLocal);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_INVALIDATED);
for (ListenerInvocation listener : cacheEntryInvalidatedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
public void notifyCacheEntryLoaded(Object key, boolean pre, InvocationContext ctx) {
if (!cacheEntryLoadedListeners.isEmpty()) {
boolean originLocal = ctx.isOriginLocal();
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(originLocal);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_LOADED);
for (ListenerInvocation listener : cacheEntryLoadedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
public void notifyCacheEntryActivated(Object key, boolean pre, InvocationContext ctx) {
if (!cacheEntryActivatedListeners.isEmpty()) {
boolean originLocal = ctx.isOriginLocal();
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(originLocal);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_ACTIVATED);
for (ListenerInvocation listener : cacheEntryActivatedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
+ private void setTx(InvocationContext ctx, EventImpl e) {
+ if (ctx.isInTxScope()) {
+ GlobalTransaction tx = ((TxInvocationContext) ctx).getClusterTransactionId();
+ e.setTransactionId(tx);
+ }
+ }
+
public void notifyCacheEntryPassivated(Object key, boolean pre, InvocationContext ctx) {
if (!cacheEntryPassivatedListeners.isEmpty()) {
- Transaction tx = ctx.getTransaction();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setPre(pre);
e.setKey(key);
- e.setTransaction(tx);
+ setTx(ctx, e);
e.setType(CACHE_ENTRY_PASSIVATED);
for (ListenerInvocation listener : cacheEntryPassivatedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
- public void notifyTransactionCompleted(Transaction transaction, boolean successful, InvocationContext ctx) {
+ public void notifyTransactionCompleted(GlobalTransaction transaction, boolean successful, InvocationContext ctx) {
if (!transactionCompletedListeners.isEmpty()) {
boolean isOriginLocal = ctx.isOriginLocal();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(isOriginLocal);
- e.setTransaction(transaction);
+ e.setTransactionId(transaction);
e.setTransactionSuccessful(successful);
e.setType(TRANSACTION_COMPLETED);
for (ListenerInvocation listener : transactionCompletedListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
- public void notifyTransactionRegistered(Transaction transaction, InvocationContext ctx) {
+ public void notifyTransactionRegistered(GlobalTransaction globalTransaction, InvocationContext ctx) {
if (!transactionRegisteredListeners.isEmpty()) {
boolean isOriginLocal = ctx.isOriginLocal();
- InvocationContext backup = resetInvocationContext(ctx);
+ Object contexts = icc.suspend();
EventImpl e = new EventImpl();
e.setCache(cache);
e.setOriginLocal(isOriginLocal);
- e.setTransaction(transaction);
+ e.setTransactionId(globalTransaction);
e.setType(TRANSACTION_REGISTERED);
for (ListenerInvocation listener : transactionRegisteredListeners) listener.invoke(e);
- restoreInvocationContext(backup);
+ icc.resume(contexts);
}
}
-
- private void restoreInvocationContext(InvocationContext backup) {
- icc.set(backup);
- }
-
- /**
- * Resets the current (passed-in) invocation, and returns a temp InvocationContext containing its state so it can be
- * restored later using {@link #restoreInvocationContext(InvocationContext)}
- *
- * @param ctx the current context to be reset
- * @return a clone of ctx, before it was reset
- */
- private InvocationContext resetInvocationContext(InvocationContext ctx) {
- // wipe current context.
- icc.reset();
- // get a new Invocation Context
- InvocationContext newContext = icc.get();
- newContext.putLookedUpEntries(ctx.getLookedUpEntries());
-// newContext.addAllKeysLocked(ctx.getKeysLocked());
- return ctx;
- }
}
Modified: trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/EventImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/EventImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/EventImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -22,9 +22,8 @@
package org.infinispan.notifications.cachelistener.event;
import org.infinispan.Cache;
+import org.infinispan.transaction.xa.GlobalTransaction;
-import javax.transaction.Transaction;
-
/**
* Basic implementation of an event that covers all event types.
*
@@ -37,23 +36,12 @@
private boolean pre = false; // by default events are after the fact
private Cache cache;
private Object key;
- private Transaction transaction;
+ private GlobalTransaction transaction;
private boolean originLocal = true; // by default events all originate locally
private boolean transactionSuccessful;
private Type type;
private Object value;
- public EventImpl(boolean pre, Cache cache, Object key, Transaction transaction, boolean originLocal, boolean successful, Type type, Object value) {
- this.pre = pre;
- this.cache = cache;
- this.key = key;
- this.transaction = transaction;
- this.originLocal = originLocal;
- this.transactionSuccessful = successful;
- this.type = type;
- this.value = value;
- }
-
public EventImpl() {
}
@@ -73,8 +61,8 @@
return key;
}
- public Transaction getTransaction() {
- return transaction;
+ public GlobalTransaction getGlobalTransaction() {
+ return this.transaction;
}
public boolean isOriginLocal() {
@@ -99,7 +87,7 @@
this.key = key;
}
- public void setTransaction(Transaction transaction) {
+ public void setTransactionId(GlobalTransaction transaction) {
this.transaction = transaction;
}
Modified: trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/TransactionalEvent.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/TransactionalEvent.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/notifications/cachelistener/event/TransactionalEvent.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,7 +21,7 @@
*/
package org.infinispan.notifications.cachelistener.event;
-import javax.transaction.Transaction;
+import org.infinispan.transaction.xa.GlobalTransaction;
/**
* An event type that includes a transaction context - if one exists - as well as a boolean as to whether the call
@@ -35,7 +35,7 @@
* @return the Transaction associated with the current call. May be null if the current call is outside the scope of
* a transaction.
*/
- Transaction getTransaction();
+ GlobalTransaction getGlobalTransaction();
/**
* @return true if the call originated on the local cache instance; false if originated from a remote one.
Modified: trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandler.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandler.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandler.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -12,7 +12,7 @@
/**
* A globally scoped component, that is able to locate named caches and invoke remotely originating calls on the
* appropriate cache. The primary goal of this component is to act as a bridge between the globally scoped {@link
- * RpcManager} and named-cache scoped components.
+ * org.infinispan.remoting.rpc.RpcManager} and named-cache scoped components.
*
* @author Manik Surtani
* @since 4.0
Modified: trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -3,7 +3,7 @@
import org.infinispan.commands.CommandsFactory;
import org.infinispan.commands.remote.CacheRpcCommand;
import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.factories.GlobalComponentRegistry;
import org.infinispan.factories.annotations.Inject;
@@ -65,7 +65,7 @@
commandsFactory.initializeReplicableCommand(cmd);
try {
- Object retval = cmd.perform(icc.get());
+ Object retval = cmd.perform(null);
return cr.getComponent(ResponseGenerator.class).getResponse(cmd, retval);
} catch (Exception e) {
return new ExceptionResponse(e);
Modified: trunk/core/src/main/java/org/infinispan/remoting/ReplicationQueue.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/ReplicationQueue.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/ReplicationQueue.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -32,6 +32,8 @@
import org.infinispan.factories.annotations.Stop;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.remoting.rpc.ResponseMode;
import java.util.ArrayList;
import java.util.LinkedList;
Deleted: trunk/core/src/main/java/org/infinispan/remoting/ResponseFilter.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/ResponseFilter.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/ResponseFilter.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,32 +0,0 @@
-package org.infinispan.remoting;
-
-import org.infinispan.remoting.responses.Response;
-import org.infinispan.remoting.transport.Address;
-
-/**
- * A mechanism of filtering RPC responses. Used with {@link org.infinispan.remoting.RpcManager#invokeRemotely(java.util.List,
- * org.infinispan.commands.ReplicableCommand, ResponseMode, long, boolean, ResponseFilter, boolean)}
- *
- * @author Manik Surtani
- * @since 4.0
- */
-public interface ResponseFilter {
- /**
- * Determines whether a response from a given sender should be added to the response list of the request
- *
- * @param response The response (usually a serializable value)
- * @param sender The sender of response
- * @return True if we should add the response to the response list of a request, otherwise false. In the latter case,
- * we don't add the response to the response list.
- */
- boolean isAcceptable(Response response, Address sender);
-
- /**
- * Right after calling {@link #isAcceptable(Response, Address)}, this method is called to see whether we are done
- * with the request and can unblock the caller
- *
- * @return False if the request is done, otherwise true
- */
- boolean needMoreResponses();
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/remoting/ResponseMode.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/ResponseMode.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/ResponseMode.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,11 +0,0 @@
-package org.infinispan.remoting;
-
-/**
- * // TODO: Manik: Document this!
- *
- * @author Manik Surtani
- * @since 4.0
- */
-public enum ResponseMode {
- SYNCHRONOUS, ASYNCHRONOUS, WAIT_FOR_VALID_RESPONSE
-}
Deleted: trunk/core/src/main/java/org/infinispan/remoting/RpcManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/RpcManager.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/RpcManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,130 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.remoting;
-
-import org.infinispan.commands.ReplicableCommand;
-import org.infinispan.factories.annotations.NonVolatile;
-import org.infinispan.factories.scopes.Scope;
-import org.infinispan.factories.scopes.Scopes;
-import org.infinispan.lifecycle.Lifecycle;
-import org.infinispan.remoting.responses.Response;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.remoting.transport.Transport;
-import org.infinispan.statetransfer.StateTransferException;
-
-import java.util.List;
-
-/**
- * Provides a mechanism for communicating with other caches in the cluster.
- * <p/>
- * Implementations have a simple lifecycle: <ul> <li>start() - starts the underlying communication channel based on
- * configuration options injected, and connects the channel</li> <li>stop() - stops the dispatcher and releases
- * resources</li> </ul>
- *
- * @author Manik Surtani
- * @since 4.0
- */
- at Scope(Scopes.GLOBAL)
- at NonVolatile
-public interface RpcManager extends Lifecycle {
- // TODO this needs to be re-thought regarding adding a transport-independent mechanism of unicasts for distribution based on consistent hashes
- /**
- * Invokes an RPC call on other caches in the cluster.
- *
- * @param recipients a list of Addresses to invoke the call on. If this is null, the call is broadcast to
- * the entire cluster.
- * @param rpcCommand the cache command to invoke
- * @param mode the response mode to use
- * @param timeout a timeout after which to throw a replication exception.
- * @param usePriorityQueue if true, a priority queue is used to deliver messages. May not be supported by all
- * implementations.
- * @param responseFilter a response filter with which to filter out failed/unwanted/invalid responses.
- * @param stateTransferEnabled if true, additional replaying is considered if messages need to be re-sent during the
- * course of a state transfer
- * @return a list of responses from each member contacted.
- * @throws Exception in the event of problems.
- */
- List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter, boolean stateTransferEnabled) throws Exception;
-
- /**
- * Invokes an RPC call on other caches in the cluster.
- *
- * @param recipients a list of Addresses to invoke the call on. If this is null, the call is broadcast to
- * the entire cluster.
- * @param rpcCommand the cache command to invoke
- * @param mode the response mode to use
- * @param timeout a timeout after which to throw a replication exception.
- * @param usePriorityQueue if true, a priority queue is used to deliver messages. May not be supported by all
- * implementations.
- * @param stateTransferEnabled if true, additional replaying is considered if messages need to be re-sent during the
- * course of a state transfer
- * @return a list of responses from each member contacted.
- * @throws Exception in the event of problems.
- */
- List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, boolean stateTransferEnabled) throws Exception;
-
- /**
- * Invokes an RPC call on other caches in the cluster.
- *
- * @param recipients a list of Addresses to invoke the call on. If this is null, the call is broadcast to
- * the entire cluster.
- * @param rpcCommand the cache command to invoke
- * @param mode the response mode to use
- * @param timeout a timeout after which to throw a replication exception.
- * @param stateTransferEnabled if true, additional replaying is considered if messages need to be re-sent during the
- * course of a state transfer
- * @return a list of responses from each member contacted.
- * @throws Exception in the event of problems.
- */
- List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean stateTransferEnabled) throws Exception;
-
- /**
- * Initiates a state retrieval process from neighbouring caches. This method will block until it either times out,
- * or state is retrieved and applied.
- *
- * @param cacheName name of cache requesting state
- * @param timeout length of time to try to retrieve state on each peer
- * @throws org.infinispan.statetransfer.StateTransferException
- * in the event of problems
- */
- void retrieveState(String cacheName, long timeout) throws StateTransferException;
-
- /**
- * @return a reference to the underlying transport.
- */
- Transport getTransport();
-
- /**
- * If {@link #retrieveState(String, long)} has been invoked and hasn't yet returned (i.e., a state transfer is in
- * progress), this method will return the current Address from which a state transfer is being attempted. Otherwise,
- * this method returns a null.
- *
- * @return the current Address from which a state transfer is being attempted, if a state transfer is in progress, or
- * a null otherwise.
- */
- Address getCurrentStateTransferSource();
-
- /**
- * Returns the local address.
- */
- public Address getLocalAddress();
-}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/remoting/RpcManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/RpcManagerImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/RpcManagerImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,225 +0,0 @@
-package org.infinispan.remoting;
-
-import org.infinispan.CacheException;
-import org.infinispan.commands.ReplicableCommand;
-import org.infinispan.config.GlobalConfiguration;
-import org.infinispan.factories.KnownComponentNames;
-import org.infinispan.factories.annotations.ComponentName;
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.factories.annotations.Start;
-import org.infinispan.factories.annotations.Stop;
-import org.infinispan.jmx.annotations.MBean;
-import org.infinispan.jmx.annotations.ManagedAttribute;
-import org.infinispan.jmx.annotations.ManagedOperation;
-import org.infinispan.marshall.Marshaller;
-import org.infinispan.notifications.cachemanagerlistener.CacheManagerNotifier;
-import org.infinispan.remoting.responses.Response;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.remoting.transport.Transport;
-import org.infinispan.statetransfer.StateTransferException;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import java.text.NumberFormat;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * This component really is just a wrapper around a {@link org.infinispan.remoting.transport.Transport} implementation,
- * and is used to set up the transport and provide lifecycle and dependency hooks into external transport
- * implementations.
- *
- * @author Manik Surtani
- * @since 4.0
- */
- at MBean(objectName = "RpcManager")
-public class RpcManagerImpl implements RpcManager {
-
- Transport t;
- private final AtomicLong replicationCount = new AtomicLong(0);
- private final AtomicLong replicationFailures = new AtomicLong(0);
- boolean statisticsEnabled = false; // by default, don't gather statistics.
- private static final Log log = LogFactory.getLog(RpcManagerImpl.class);
- private volatile Address currentStateTransferSource;
-
- @Inject
- public void injectDependencies(GlobalConfiguration globalConfiguration, Transport t, InboundInvocationHandler handler,
- Marshaller marshaller,
- @ComponentName(KnownComponentNames.ASYNC_SERIALIZATION_EXECUTOR) ExecutorService e,
- CacheManagerNotifier notifier) {
- this.t = t;
- this.t.initialize(globalConfiguration, globalConfiguration.getTransportProperties(), marshaller, e, handler,
- notifier, globalConfiguration.getDistributedSyncTimeout());
- }
-
- @Start(priority = 10)
- public void start() {
- t.start();
- }
-
- @Stop
- public void stop() {
- t.stop();
- }
-
- public List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter, boolean stateTransferEnabled) throws Exception {
- try {
- List<Response> result = t.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, responseFilter, stateTransferEnabled);
- if (isStatisticsEnabled()) replicationCount.incrementAndGet();
- return result;
- } catch (Throwable e) {
- if (isStatisticsEnabled()) replicationFailures.incrementAndGet();
- throw new CacheException(e);
- }
- }
-
- public List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, boolean stateTransferEnabled) throws Exception {
- return invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, null, stateTransferEnabled);
- }
-
- public List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean stateTransferEnabled) throws Exception {
- return invokeRemotely(recipients, rpcCommand, mode, timeout, false, null, stateTransferEnabled);
- }
-
- public void retrieveState(String cacheName, long timeout) throws StateTransferException {
- if (t.isSupportStateTransfer()) {
- // TODO make these configurable
- Random r = new Random();
- int initialWaitTime = (r.nextInt(10) + 1) * 100; // millis
- int waitTimeIncreaseFactor = 2;
- int numRetries = 5;
- List<Address> members = t.getMembers();
- if (members.size() < 2) {
- if (log.isDebugEnabled())
- log.debug("We're the only member in the cluster; no one to retrieve state from. Not doing anything!");
- return;
- }
-
- boolean success = false;
-
- try {
-
- outer:
- for (int i = 0, wait = initialWaitTime; i < numRetries; i++) {
- for (Address member : members) {
- if (!member.equals(t.getAddress())) {
- try {
- if (log.isInfoEnabled()) log.info("Trying to fetch state from {0}", member);
- currentStateTransferSource = member;
- if (t.retrieveState(cacheName, member, timeout)) {
- if (log.isInfoEnabled())
- log.info("Successfully retrieved and applied state from {0}", member);
- success = true;
- break outer;
- }
- } catch (StateTransferException e) {
- if (log.isDebugEnabled()) log.debug("Error while fetching state from member " + member, e);
- } finally {
- currentStateTransferSource = null;
- }
- }
- }
-
- if (!success) {
- if (log.isWarnEnabled())
- log.warn("Could not find available peer for state, backing off and retrying");
-
- try {
- Thread.sleep(wait *= waitTimeIncreaseFactor);
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
-
- }
- } finally {
- currentStateTransferSource = null;
- }
-
- if (!success) throw new StateTransferException("Unable to fetch state on startup");
- } else {
- throw new StateTransferException("Transport does not, or is not configured to, support state transfer. Please disable fetching state on startup, or reconfigure your transport.");
- }
- }
-
- public Transport getTransport() {
- return t;
- }
-
- public Address getCurrentStateTransferSource() {
- return currentStateTransferSource;
- }
-
- public Address getLocalAddress() {
- if (t == null) {
- return null;
- }
- return t.getAddress();
- }
-
- // -------------------------------------------- JMX information -----------------------------------------------
-
- @ManagedOperation
- public void resetStatistics() {
- replicationCount.set(0);
- replicationFailures.set(0);
- }
-
- @ManagedAttribute(description = "number of successful replications")
- public String getReplicationCount() {
- if (!isStatisticsEnabled()) {
- return "N/A";
- }
- return String.valueOf(replicationCount.get());
- }
-
- @ManagedAttribute(description = "number of failed replications")
- public String getReplicationFailures() {
- if (!isStatisticsEnabled()) {
- return "N/A";
- }
- return String.valueOf(replicationFailures.get());
- }
-
- @ManagedAttribute(description = "whether or not jmx statistics are enabled")
- public boolean isStatisticsEnabled() {
- return statisticsEnabled;
- }
-
- @ManagedAttribute
- public void setStatisticsEnabled(boolean statisticsEnabled) {
- this.statisticsEnabled = statisticsEnabled;
- }
-
- @ManagedAttribute
- public String getAddress() {
- if (t == null || !isStatisticsEnabled()) return "N/A";
- Address address = t.getAddress();
- return address == null ? "N/A" : address.toString();
- }
-
- @ManagedAttribute
- public String getMembers() {
- if (t == null || !isStatisticsEnabled()) return "N/A";
- List<Address> addressList = t.getMembers();
- return addressList.toString();
- }
-
- @ManagedAttribute
- public String getSuccessRatio() {
- if (replicationCount.get() == 0 || !statisticsEnabled) {
- return "N/A";
- }
- double totalCount = replicationCount.get() + replicationFailures.get();
- double ration = (double) replicationCount.get() / totalCount * 100d;
- return NumberFormat.getInstance().format(ration) + "%";
- }
-
- // mainly for unit testing
- public void setTransport(Transport t) {
- this.t = t;
- }
-}
Modified: trunk/core/src/main/java/org/infinispan/remoting/responses/ClusteredGetResponseValidityFilter.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/responses/ClusteredGetResponseValidityFilter.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/responses/ClusteredGetResponseValidityFilter.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,6 +1,6 @@
package org.infinispan.remoting.responses;
-import org.infinispan.remoting.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseFilter;
import org.infinispan.remoting.transport.Address;
import java.util.Collection;
Added: trunk/core/src/main/java/org/infinispan/remoting/rpc/CacheRpcManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/rpc/CacheRpcManager.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/remoting/rpc/CacheRpcManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,127 @@
+package org.infinispan.remoting.rpc;
+
+import org.infinispan.CacheException;
+import org.infinispan.commands.CommandsFactory;
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.commands.remote.CacheRpcCommand;
+import org.infinispan.commands.remote.SingleRpcCommand;
+import org.infinispan.config.Configuration;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.factories.annotations.Start;
+import org.infinispan.remoting.ReplicationException;
+import org.infinispan.remoting.ReplicationQueue;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import java.util.List;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public class CacheRpcManager {
+
+ private static Log log = LogFactory.getLog(CacheRpcManager.class);
+
+ private Configuration configuration;
+ private boolean stateTransferEnabled;
+
+ private ReplicationQueue replicationQueue;
+ private RpcManager rpcManager;
+ private CommandsFactory commandsFactory;
+
+
+ @Inject
+ public void init(ReplicationQueue replicationQueue, RpcManager rpcManager, CommandsFactory commandsFactory, Configuration configuration) {
+ this.replicationQueue = replicationQueue;
+ this.rpcManager = rpcManager;
+ this.commandsFactory = commandsFactory;
+ this.configuration = configuration;
+ }
+
+ @Start
+ public void init() {
+ stateTransferEnabled = configuration.isFetchInMemoryState();
+ }
+
+ public void broadcastRpcCommand(CacheRpcCommand rpc, boolean sync, boolean useOutOfBandMessage) throws ReplicationException {
+ if (useReplicationQueue(sync)) {
+ replicationQueue.add(rpc);
+ } else {
+ multicastRpcCommand(null, rpc, sync, useOutOfBandMessage);
+ }
+ }
+
+ public void broadcastReplicableCommand(ReplicableCommand call, boolean sync) throws ReplicationException {
+ multicastReplicableCommand(null, call, sync);
+ }
+
+ public void multicastReplicableCommand(List<Address> members, ReplicableCommand call, boolean sync) throws ReplicationException {
+ if (useReplicationQueue(sync)) {
+ replicationQueue.add(call);
+ } else {
+ SingleRpcCommand rpcCommand = commandsFactory.buildSingleRpcCommand(call);
+ multicastRpcCommand(members, rpcCommand, sync, false);
+ }
+ }
+
+ public void multicastRpcCommand(List<Address> recipients, CacheRpcCommand command, boolean sync, boolean useOutOfBandMessage) throws ReplicationException {
+ if (log.isTraceEnabled()) {
+ log.trace("invoking method " + command.getClass().getSimpleName() + ", members=" + rpcManager.getTransport().getMembers() + ", mode=" +
+ configuration.getCacheMode() + ", exclude_self=" + true + ", timeout=" +
+ configuration.getSyncReplTimeout());
+ log.trace("Broadcasting call " + command + " to recipient list " + recipients);
+ }
+
+ List rsps;
+ try {
+ rsps = rpcManager.invokeRemotely(recipients,
+ command,
+ sync ? ResponseMode.SYNCHRONOUS : ResponseMode.ASYNCHRONOUS, // is synchronised?
+ configuration.getSyncReplTimeout(), useOutOfBandMessage, stateTransferEnabled
+ );
+ if (log.isTraceEnabled()) log.trace("responses=" + rsps);
+ if (sync) checkResponses(rsps);
+ } catch (CacheException e) {
+ log.error("Replication exception",e);
+ throw e;
+ } catch (Exception ex) {
+ log.error("Unexpected exception",ex);
+ throw new ReplicationException("Unexpected exception while replicating", ex);
+ }
+ }
+
+ public boolean isClusterStarted() {
+ return rpcManager != null && rpcManager.getTransport() != null && rpcManager.getTransport().getMembers() != null
+ && rpcManager.getTransport().getMembers().size() > 1;
+ }
+
+ private boolean useReplicationQueue(boolean sync) {
+ return !sync && replicationQueue != null;
+ }
+
+ /**
+ * Checks whether any of the responses are exceptions. If yes, re-throws them (as exceptions or runtime exceptions).
+ */
+ private void checkResponses(List rsps) {
+ if (rsps != null) {
+ for (Object rsp : rsps) {
+ if (rsp != null && rsp instanceof Throwable) {
+ // lets print a stack trace first.
+ Throwable throwable = (Throwable) rsp;
+ if (log.isDebugEnabled()) {
+ log.debug("Received Throwable from remote cache", throwable);
+ }
+ throw new ReplicationException(throwable);
+ }
+ }
+ }
+ }
+
+ public Address getLocalAddress() {
+ return rpcManager != null ? rpcManager.getLocalAddress() : null;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/remoting/rpc/CacheRpcManager.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseFilter.java (from rev 204, trunk/core/src/main/java/org/infinispan/remoting/ResponseFilter.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseFilter.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseFilter.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,32 @@
+package org.infinispan.remoting.rpc;
+
+import org.infinispan.remoting.responses.Response;
+import org.infinispan.remoting.transport.Address;
+
+/**
+ * A mechanism of filtering RPC responses. Used with {@link RpcManager#invokeRemotely(java.util.List,
+ * org.infinispan.commands.ReplicableCommand, ResponseMode, long, boolean, ResponseFilter, boolean)}
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public interface ResponseFilter {
+ /**
+ * Determines whether a response from a given sender should be added to the response list of the request
+ *
+ * @param response The response (usually a serializable value)
+ * @param sender The sender of response
+ * @return True if we should add the response to the response list of a request, otherwise false. In the latter case,
+ * we don't add the response to the response list.
+ */
+ boolean isAcceptable(Response response, Address sender);
+
+ /**
+ * Right after calling {@link #isAcceptable(Response, Address)}, this method is called to see whether we are done
+ * with the request and can unblock the caller
+ *
+ * @return False if the request is done, otherwise true
+ */
+ boolean needMoreResponses();
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseFilter.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseMode.java (from rev 204, trunk/core/src/main/java/org/infinispan/remoting/ResponseMode.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseMode.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseMode.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,11 @@
+package org.infinispan.remoting.rpc;
+
+/**
+ * // TODO: Manik: Document this!
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public enum ResponseMode {
+ SYNCHRONOUS, ASYNCHRONOUS, WAIT_FOR_VALID_RESPONSE
+}
Property changes on: trunk/core/src/main/java/org/infinispan/remoting/rpc/ResponseMode.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManager.java (from rev 204, trunk/core/src/main/java/org/infinispan/remoting/RpcManager.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManager.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,130 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.remoting.rpc;
+
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.factories.annotations.NonVolatile;
+import org.infinispan.factories.scopes.Scope;
+import org.infinispan.factories.scopes.Scopes;
+import org.infinispan.lifecycle.Lifecycle;
+import org.infinispan.remoting.responses.Response;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.Transport;
+import org.infinispan.statetransfer.StateTransferException;
+
+import java.util.List;
+
+/**
+ * Provides a mechanism for communicating with other caches in the cluster.
+ * <p/>
+ * Implementations have a simple lifecycle: <ul> <li>start() - starts the underlying communication channel based on
+ * configuration options injected, and connects the channel</li> <li>stop() - stops the dispatcher and releases
+ * resources</li> </ul>
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+ at Scope(Scopes.GLOBAL)
+ at NonVolatile
+public interface RpcManager extends Lifecycle {
+ // TODO this needs to be re-thought regarding adding a transport-independent mechanism of unicasts for distribution based on consistent hashes
+ /**
+ * Invokes an RPC call on other caches in the cluster.
+ *
+ * @param recipients a list of Addresses to invoke the call on. If this is null, the call is broadcast to
+ * the entire cluster.
+ * @param rpcCommand the cache command to invoke
+ * @param mode the response mode to use
+ * @param timeout a timeout after which to throw a replication exception.
+ * @param usePriorityQueue if true, a priority queue is used to deliver messages. May not be supported by all
+ * implementations.
+ * @param responseFilter a response filter with which to filter out failed/unwanted/invalid responses.
+ * @param stateTransferEnabled if true, additional replaying is considered if messages need to be re-sent during the
+ * course of a state transfer
+ * @return a list of responses from each member contacted.
+ * @throws Exception in the event of problems.
+ */
+ List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter, boolean stateTransferEnabled) throws Exception;
+
+ /**
+ * Invokes an RPC call on other caches in the cluster.
+ *
+ * @param recipients a list of Addresses to invoke the call on. If this is null, the call is broadcast to
+ * the entire cluster.
+ * @param rpcCommand the cache command to invoke
+ * @param mode the response mode to use
+ * @param timeout a timeout after which to throw a replication exception.
+ * @param usePriorityQueue if true, a priority queue is used to deliver messages. May not be supported by all
+ * implementations.
+ * @param stateTransferEnabled if true, additional replaying is considered if messages need to be re-sent during the
+ * course of a state transfer
+ * @return a list of responses from each member contacted.
+ * @throws Exception in the event of problems.
+ */
+ List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, boolean stateTransferEnabled) throws Exception;
+
+ /**
+ * Invokes an RPC call on other caches in the cluster.
+ *
+ * @param recipients a list of Addresses to invoke the call on. If this is null, the call is broadcast to
+ * the entire cluster.
+ * @param rpcCommand the cache command to invoke
+ * @param mode the response mode to use
+ * @param timeout a timeout after which to throw a replication exception.
+ * @param stateTransferEnabled if true, additional replaying is considered if messages need to be re-sent during the
+ * course of a state transfer
+ * @return a list of responses from each member contacted.
+ * @throws Exception in the event of problems.
+ */
+ List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean stateTransferEnabled) throws Exception;
+
+ /**
+ * Initiates a state retrieval process from neighbouring caches. This method will block until it either times out,
+ * or state is retrieved and applied.
+ *
+ * @param cacheName name of cache requesting state
+ * @param timeout length of time to try to retrieve state on each peer
+ * @throws org.infinispan.statetransfer.StateTransferException
+ * in the event of problems
+ */
+ void retrieveState(String cacheName, long timeout) throws StateTransferException;
+
+ /**
+ * @return a reference to the underlying transport.
+ */
+ Transport getTransport();
+
+ /**
+ * If {@link #retrieveState(String, long)} has been invoked and hasn't yet returned (i.e., a state transfer is in
+ * progress), this method will return the current Address from which a state transfer is being attempted. Otherwise,
+ * this method returns a null.
+ *
+ * @return the current Address from which a state transfer is being attempted, if a state transfer is in progress, or
+ * a null otherwise.
+ */
+ Address getCurrentStateTransferSource();
+
+ /**
+ * Returns the local address.
+ */
+ public Address getLocalAddress();
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManager.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManagerImpl.java (from rev 204, trunk/core/src/main/java/org/infinispan/remoting/RpcManagerImpl.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManagerImpl.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManagerImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,232 @@
+package org.infinispan.remoting.rpc;
+
+import org.infinispan.CacheException;
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.config.GlobalConfiguration;
+import org.infinispan.factories.KnownComponentNames;
+import org.infinispan.factories.annotations.ComponentName;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.factories.annotations.Start;
+import org.infinispan.factories.annotations.Stop;
+import org.infinispan.jmx.annotations.MBean;
+import org.infinispan.jmx.annotations.ManagedAttribute;
+import org.infinispan.jmx.annotations.ManagedOperation;
+import org.infinispan.marshall.Marshaller;
+import org.infinispan.notifications.cachemanagerlistener.CacheManagerNotifier;
+import org.infinispan.remoting.InboundInvocationHandler;
+import org.infinispan.remoting.responses.Response;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.Transport;
+import org.infinispan.statetransfer.StateTransferException;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import java.text.NumberFormat;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * This component really is just a wrapper around a {@link org.infinispan.remoting.transport.Transport} implementation,
+ * and is used to set up the transport and provide lifecycle and dependency hooks into external transport
+ * implementations.
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+ at MBean(objectName = "RpcManager")
+public class RpcManagerImpl implements RpcManager {
+
+ private static final Log log = LogFactory.getLog(RpcManagerImpl.class);
+
+ Transport t;
+ private final AtomicLong replicationCount = new AtomicLong(0);
+ private final AtomicLong replicationFailures = new AtomicLong(0);
+ boolean statisticsEnabled = false; // by default, don't gather statistics.
+ private volatile Address currentStateTransferSource;
+
+ @Inject
+ public void injectDependencies(GlobalConfiguration globalConfiguration, Transport t, InboundInvocationHandler handler,
+ Marshaller marshaller,
+ @ComponentName(KnownComponentNames.ASYNC_SERIALIZATION_EXECUTOR) ExecutorService e,
+ CacheManagerNotifier notifier) {
+ this.t = t;
+ this.t.initialize(globalConfiguration, globalConfiguration.getTransportProperties(), marshaller, e, handler,
+ notifier, globalConfiguration.getDistributedSyncTimeout());
+ }
+
+ @Start(priority = 10)
+ public void start() {
+ t.start();
+ }
+
+ @Stop
+ public void stop() {
+ t.stop();
+ }
+
+ public List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter, boolean stateTransferEnabled) throws Exception {
+ try {
+ List<Response> result = t.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, responseFilter, stateTransferEnabled);
+ if (isStatisticsEnabled()) replicationCount.incrementAndGet();
+ return result;
+ } catch (CacheException e) {
+ if (log.isTraceEnabled()) log.trace("replicaiton exception: ", e);
+ if (isStatisticsEnabled()) replicationFailures.incrementAndGet();
+ throw e;
+ } catch (Throwable th) {
+ log.error("unexpected error while replicating", th);
+ if (isStatisticsEnabled()) replicationFailures.incrementAndGet();
+ throw new CacheException(th);
+ }
+ }
+
+ public List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, boolean stateTransferEnabled) throws Exception {
+ return invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, null, stateTransferEnabled);
+ }
+
+ public List<Response> invokeRemotely(List<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean stateTransferEnabled) throws Exception {
+ return invokeRemotely(recipients, rpcCommand, mode, timeout, false, null, stateTransferEnabled);
+ }
+
+ public void retrieveState(String cacheName, long timeout) throws StateTransferException {
+ if (t.isSupportStateTransfer()) {
+ // TODO make these configurable
+ Random r = new Random();
+ int initialWaitTime = (r.nextInt(10) + 1) * 100; // millis
+ int waitTimeIncreaseFactor = 2;
+ int numRetries = 5;
+ List<Address> members = t.getMembers();
+ if (members.size() < 2) {
+ if (log.isDebugEnabled())
+ log.debug("We're the only member in the cluster; no one to retrieve state from. Not doing anything!");
+ return;
+ }
+
+ boolean success = false;
+
+ try {
+
+ outer:
+ for (int i = 0, wait = initialWaitTime; i < numRetries; i++) {
+ for (Address member : members) {
+ if (!member.equals(t.getAddress())) {
+ try {
+ if (log.isInfoEnabled()) log.info("Trying to fetch state from {0}", member);
+ currentStateTransferSource = member;
+ if (t.retrieveState(cacheName, member, timeout)) {
+ if (log.isInfoEnabled())
+ log.info("Successfully retrieved and applied state from {0}", member);
+ success = true;
+ break outer;
+ }
+ } catch (StateTransferException e) {
+ if (log.isDebugEnabled()) log.debug("Error while fetching state from member " + member, e);
+ } finally {
+ currentStateTransferSource = null;
+ }
+ }
+ }
+
+ if (!success) {
+ if (log.isWarnEnabled())
+ log.warn("Could not find available peer for state, backing off and retrying");
+
+ try {
+ Thread.sleep(wait *= waitTimeIncreaseFactor);
+ }
+ catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ }
+ } finally {
+ currentStateTransferSource = null;
+ }
+
+ if (!success) throw new StateTransferException("Unable to fetch state on startup");
+ } else {
+ throw new StateTransferException("Transport does not, or is not configured to, support state transfer. Please disable fetching state on startup, or reconfigure your transport.");
+ }
+ }
+
+ public Transport getTransport() {
+ return t;
+ }
+
+ public Address getCurrentStateTransferSource() {
+ return currentStateTransferSource;
+ }
+
+ public Address getLocalAddress() {
+ if (t == null) {
+ return null;
+ }
+ return t.getAddress();
+ }
+
+ // -------------------------------------------- JMX information -----------------------------------------------
+
+ @ManagedOperation
+ public void resetStatistics() {
+ replicationCount.set(0);
+ replicationFailures.set(0);
+ }
+
+ @ManagedAttribute(description = "number of successful replications")
+ public String getReplicationCount() {
+ if (!isStatisticsEnabled()) {
+ return "N/A";
+ }
+ return String.valueOf(replicationCount.get());
+ }
+
+ @ManagedAttribute(description = "number of failed replications")
+ public String getReplicationFailures() {
+ if (!isStatisticsEnabled()) {
+ return "N/A";
+ }
+ return String.valueOf(replicationFailures.get());
+ }
+
+ @ManagedAttribute(description = "whether or not jmx statistics are enabled")
+ public boolean isStatisticsEnabled() {
+ return statisticsEnabled;
+ }
+
+ @ManagedAttribute
+ public void setStatisticsEnabled(boolean statisticsEnabled) {
+ this.statisticsEnabled = statisticsEnabled;
+ }
+
+ @ManagedAttribute
+ public String getAddress() {
+ if (t == null || !isStatisticsEnabled()) return "N/A";
+ Address address = t.getAddress();
+ return address == null ? "N/A" : address.toString();
+ }
+
+ @ManagedAttribute
+ public String getMembers() {
+ if (t == null || !isStatisticsEnabled()) return "N/A";
+ List<Address> addressList = t.getMembers();
+ return addressList.toString();
+ }
+
+ @ManagedAttribute
+ public String getSuccessRatio() {
+ if (replicationCount.get() == 0 || !statisticsEnabled) {
+ return "N/A";
+ }
+ double totalCount = replicationCount.get() + replicationFailures.get();
+ double ration = (double) replicationCount.get() / totalCount * 100d;
+ return NumberFormat.getInstance().format(ration) + "%";
+ }
+
+ // mainly for unit testing
+ public void setTransport(Transport t) {
+ this.t = t;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/remoting/rpc/RpcManagerImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/core/src/main/java/org/infinispan/remoting/transport/Transport.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/transport/Transport.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/transport/Transport.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -9,8 +9,8 @@
import org.infinispan.marshall.Marshaller;
import org.infinispan.notifications.cachemanagerlistener.CacheManagerNotifier;
import org.infinispan.remoting.InboundInvocationHandler;
-import org.infinispan.remoting.ResponseFilter;
-import org.infinispan.remoting.ResponseMode;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
import org.infinispan.remoting.responses.Response;
import org.infinispan.statetransfer.StateTransferException;
Modified: trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsResponseFilterAdapter.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsResponseFilterAdapter.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsResponseFilterAdapter.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,12 +1,12 @@
package org.infinispan.remoting.transport.jgroups;
-import org.infinispan.remoting.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseFilter;
import org.infinispan.remoting.responses.Response;
import org.jgroups.Address;
import org.jgroups.blocks.RspFilter;
/**
- * Acts as a bridge between JGroups RspFilter and {@link org.infinispan.remoting.ResponseFilter}.
+ * Acts as a bridge between JGroups RspFilter and {@link org.infinispan.remoting.rpc.ResponseFilter}.
*
* @author Manik Surtani
* @since 4.0
Modified: trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -8,8 +8,8 @@
import org.infinispan.notifications.cachemanagerlistener.CacheManagerNotifier;
import org.infinispan.remoting.InboundInvocationHandler;
import org.infinispan.remoting.ReplicationException;
-import org.infinispan.remoting.ResponseFilter;
-import org.infinispan.remoting.ResponseMode;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
import org.infinispan.remoting.responses.ExceptionResponse;
import org.infinispan.remoting.responses.Response;
import org.infinispan.remoting.transport.Address;
@@ -372,7 +372,7 @@
// and roll back any tx and break any locks
// List<org.jgroups.Address> removed = toJGroupsAddressList(members);
// removed.removeAll(newMembers);
-// spi.getInvocationContext().getOptionOverrides().setSkipCacheStatusCheck(true);
+// spi.getLocalInvocationContext().getOptionOverrides().setSkipCacheStatusCheck(true);
// if (root != null)
// {
//removeLocksForDeadMembers(root.getDelegationTarget(), removed);
Modified: trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -31,7 +31,7 @@
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.interceptors.InterceptorChain;
@@ -41,8 +41,8 @@
import org.infinispan.loaders.CacheLoaderManager;
import org.infinispan.loaders.CacheStore;
import org.infinispan.marshall.Marshaller;
-import org.infinispan.remoting.ResponseMode;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.DistributedSync;
import org.infinispan.transaction.TransactionLog;
@@ -215,12 +215,12 @@
if (trace) log.trace("Applying commit log");
Object object = marshaller.objectFromObjectStream(oi);
while (object instanceof TransactionLog.LogEntry) {
- WriteCommand[] mods = ((TransactionLog.LogEntry) object).getModifications();
+ TransactionLog.LogEntry logEntry = (TransactionLog.LogEntry) object;
+ WriteCommand[] mods = logEntry.getModifications();
if (trace) log.trace("Mods = {0}", Arrays.toString(mods));
for (WriteCommand mod : mods) {
commandsFactory.initializeReplicableCommand(mod);
- InvocationContext ctx = invocationContextContainer.get();
- ctx.setOriginLocal(false);
+ InvocationContext ctx = invocationContextContainer.getRemoteTxInvocationContext(logEntry.getTransaction(),true);
ctx.setFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_CACHE_STATUS_CHECK);
interceptorChain.invoke(ctx, mod);
}
@@ -254,8 +254,7 @@
if (!transactionLog.hasPendingPrepare(command)) {
if (trace) log.trace("Applying pending prepare {0}", command);
commandsFactory.initializeReplicableCommand(command);
- InvocationContext ctx = invocationContextContainer.get();
- ctx.setOriginLocal(false);
+ InvocationContext ctx = invocationContextContainer.getRemoteTxInvocationContext(command.getGlobalTransaction(), true);
ctx.setFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_CACHE_STATUS_CHECK);
interceptorChain.invoke(ctx, command);
} else {
Deleted: trunk/core/src/main/java/org/infinispan/transaction/BatchModeTransactionManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/BatchModeTransactionManager.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/BatchModeTransactionManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,54 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-/**
- * Not really a transaction manager in the truest sense of the word. Only used to batch up operations. Proper
- * transactional symantics of rollbacks and recovery are NOT used here. This is used by PojoCache.
- *
- * @author bela
- * <p/>
- * Date: May 15, 2003 Time: 4:11:37 PM
- * @since 4.0
- */
-public class BatchModeTransactionManager extends DummyBaseTransactionManager {
- static BatchModeTransactionManager instance = null;
- static Log log = LogFactory.getLog(BatchModeTransactionManager.class);
- private static final long serialVersionUID = 5656602677430350961L;
-
- public static BatchModeTransactionManager getInstance() {
- if (instance == null) {
- instance = new BatchModeTransactionManager();
- }
- return instance;
- }
-
- public static void destroy() {
- if (instance == null) return;
- instance.setTransaction(null);
- instance = null;
- }
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/DummyBaseTransactionManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/DummyBaseTransactionManager.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/DummyBaseTransactionManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,215 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-/**
- * @author bela
- * @since 4.0
- */
-public class DummyBaseTransactionManager implements TransactionManager {
- static ThreadLocal<DummyTransaction> thread_local = new ThreadLocal<DummyTransaction>();
- private static final Log log = LogFactory.getLog(DummyBaseTransactionManager.class);
- private static final boolean trace = log.isTraceEnabled();
-
- /**
- * Starts a new transaction, and associate it with the calling thread.
- *
- * @throws javax.transaction.NotSupportedException
- * If the calling thread is already associated with a transaction, and nested transactions are not
- * supported.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public void begin() throws NotSupportedException, SystemException {
- Transaction currentTx;
- if ((currentTx = getTransaction()) != null)
- throw new NotSupportedException(Thread.currentThread() +
- " is already associated with a transaction (" + currentTx + ")");
- DummyTransaction tx = new DummyTransaction(this);
- setTransaction(tx);
- }
-
- /**
- * Commit the transaction associated with the calling thread.
- *
- * @throws javax.transaction.RollbackException
- * If the transaction was marked for rollback only, the transaction is rolled back and
- * this exception is thrown.
- * @throws IllegalStateException If the calling thread is not associated with a transaction.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- * @throws javax.transaction.HeuristicMixedException
- * If a heuristic decision was made and some some parts of the transaction have been
- * committed while other parts have been rolled back.
- * @throws javax.transaction.HeuristicRollbackException
- * If a heuristic decision to roll back the transaction was made.
- * @throws SecurityException If the caller is not allowed to commit this transaction.
- */
- public void commit() throws RollbackException, HeuristicMixedException,
- HeuristicRollbackException, SecurityException,
- IllegalStateException, SystemException {
- int status;
- DummyTransaction tx = getTransaction();
- if (tx == null)
- throw new IllegalStateException("thread not associated with transaction");
- status = tx.getStatus();
- if (status == Status.STATUS_MARKED_ROLLBACK) {
- tx.setStatus(Status.STATUS_ROLLEDBACK);
- rollback();
- throw new RollbackException("Transaction status is Status.STATUS_MARKED_ROLLBACK");
- } else {
- tx.commit();
- }
-
- // Disassociate tx from thread.
- setTransaction(null);
- }
-
- /**
- * Rolls back the transaction associated with the calling thread.
- *
- * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
- * because the calling thread is not associated with a transaction, or because it is in
- * the {@link javax.transaction.Status#STATUS_PREPARED prepared state}.
- * @throws SecurityException If the caller is not allowed to roll back this transaction.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public void rollback() throws IllegalStateException, SecurityException,
- SystemException {
- Transaction tx = getTransaction();
- if (tx == null)
- throw new IllegalStateException("no transaction associated with thread");
- tx.rollback();
-
- // Disassociate tx from thread.
- setTransaction(null);
- }
-
- /**
- * Mark the transaction associated with the calling thread for rollback only.
- *
- * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
- * because the calling thread is not associated with a transaction, or because it is in
- * the {@link javax.transaction.Status#STATUS_PREPARED prepared state}.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public void setRollbackOnly() throws IllegalStateException, SystemException {
- Transaction tx = getTransaction();
- if (tx == null)
- throw new IllegalStateException("no transaction associated with calling thread");
- tx.setRollbackOnly();
- }
-
- /**
- * Get the status of the transaction associated with the calling thread.
- *
- * @return The status of the transaction. This is one of the {@link javax.transaction.Status} constants. If no
- * transaction is associated with the calling thread, {@link javax.transaction.Status#STATUS_NO_TRANSACTION}
- * is returned.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public int getStatus() throws SystemException {
- Transaction tx = getTransaction();
- return tx != null ? tx.getStatus() : Status.STATUS_NO_TRANSACTION;
- }
-
- /**
- * Get the transaction associated with the calling thread.
- *
- * @return The transaction associated with the calling thread, or <code>null</code> if the calling thread is not
- * associated with a transaction.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public DummyTransaction getTransaction() throws SystemException {
- return thread_local.get();
- }
-
- /**
- * Change the transaction timeout for transactions started by the calling thread with the {@link #begin()} method.
- *
- * @param seconds The new timeout value, in seconds. If this parameter is <code>0</code>, the timeout value is reset
- * to the default value.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public void setTransactionTimeout(int seconds) throws SystemException {
- throw new SystemException("not supported");
- }
-
- /**
- * Suspend the association the calling thread has to a transaction, and return the suspended transaction. When
- * returning from this method, the calling thread is no longer associated with a transaction.
- *
- * @return The transaction that the calling thread was associated with, or <code>null</code> if the calling thread
- * was not associated with a transaction.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public Transaction suspend() throws SystemException {
- Transaction retval = getTransaction();
- setTransaction(null);
- if (trace) log.trace("Suspending tx " + retval);
- return retval;
- }
-
- /**
- * Resume the association of the calling thread with the given transaction.
- *
- * @param tx The transaction to be associated with the calling thread.
- * @throws javax.transaction.InvalidTransactionException
- * If the argument does not represent a valid transaction.
- * @throws IllegalStateException If the calling thread is already associated with a transaction.
- * @throws javax.transaction.SystemException
- * If the transaction service fails in an unexpected way.
- */
- public void resume(Transaction tx) throws InvalidTransactionException, IllegalStateException, SystemException {
- if (trace) log.trace("Resuming tx " + tx);
- setTransaction(tx);
- }
-
- /**
- * Just used for unit tests
- *
- * @param tx
- */
- public void setTransaction(Transaction tx) {
- thread_local.set((DummyTransaction) tx);
- }
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/DummyTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/DummyTransaction.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/DummyTransaction.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,257 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.xa.XAResource;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-/**
- * @author bela
- * @since 4.0
- */
-public class DummyTransaction implements Transaction {
- private int status = Status.STATUS_UNKNOWN;
- private static final Log log = LogFactory.getLog(DummyTransaction.class);
- protected DummyBaseTransactionManager tm_;
-
- protected final Set<Synchronization> participants = new CopyOnWriteArraySet<Synchronization>();
-
- public DummyTransaction(DummyBaseTransactionManager tm) {
- tm_ = tm;
- status = Status.STATUS_ACTIVE;
- }
-
- /**
- * Attempt to commit this transaction.
- *
- * @throws RollbackException If the transaction was marked for rollback only, the transaction is rolled back
- * and this exception is thrown.
- * @throws SystemException If the transaction service fails in an unexpected way.
- * @throws HeuristicMixedException If a heuristic decision was made and some some parts of the transaction have
- * been committed while other parts have been rolled back.
- * @throws HeuristicRollbackException If a heuristic decision to roll back the transaction was made.
- * @throws SecurityException If the caller is not allowed to commit this transaction.
- */
- public void commit()
- throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
- SecurityException, SystemException {
- boolean doCommit;
- status = Status.STATUS_PREPARING;
- try {
- boolean outcome = notifyBeforeCompletion();
- // status=Status.STATUS_PREPARED;
- if (outcome && status != Status.STATUS_MARKED_ROLLBACK) {
- status = Status.STATUS_COMMITTING;
- doCommit = true;
- } else {
- status = Status.STATUS_ROLLING_BACK;
- doCommit = false;
- }
- notifyAfterCompletion(doCommit ? Status.STATUS_COMMITTED : Status.STATUS_MARKED_ROLLBACK);
- status = doCommit ? Status.STATUS_COMMITTED : Status.STATUS_MARKED_ROLLBACK;
- if (!doCommit) throw new RollbackException("outcome is " + outcome + " status: " + status);
- }
- finally {
- // Disassociate tx from thread.
- tm_.setTransaction(null);
- }
- }
-
- /**
- * Rolls back this transaction.
- *
- * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
- * because the transaction is no longer active, or because it is in the {@link
- * Status#STATUS_PREPARED prepared state}.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void rollback() throws IllegalStateException, SystemException {
- try {
- // JBCACHE-360 -- to match JBossTM (and presumable the spec) a
- // rollback transaction should have status ROLLEDBACK before
- // calling afterCompletion().
- //status=Status.STATUS_ROLLING_BACK;
- status = Status.STATUS_ROLLEDBACK;
- notifyAfterCompletion(Status.STATUS_ROLLEDBACK);
- }
- catch (Throwable t) {
- }
- status = Status.STATUS_ROLLEDBACK;
-
- // Disassociate tx from thread.
- tm_.setTransaction(null);
- }
-
- /**
- * Mark the transaction so that the only possible outcome is a rollback.
- *
- * @throws IllegalStateException If the transaction is not in an active state.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void setRollbackOnly() throws IllegalStateException, SystemException {
- status = Status.STATUS_MARKED_ROLLBACK;
- }
-
- /**
- * Get the status of the transaction.
- *
- * @return The status of the transaction. This is one of the {@link Status} constants.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public int getStatus() throws SystemException {
- return status;
- }
-
- /**
- * Change the transaction timeout for transactions started by the calling thread with the {@link
- * DummyTransactionManager#begin()} method.
- *
- * @param seconds The new timeout value, in seconds. If this parameter is <code>0</code>, the timeout value is reset
- * to the default value.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void setTransactionTimeout(int seconds) throws SystemException {
- throw new SystemException("not supported");
- }
-
- /**
- * Enlist an XA resource with this transaction.
- *
- * @return <code>true</code> if the resource could be enlisted with this transaction, otherwise <code>false</code>.
- * @throws RollbackException If the transaction is marked for rollback only.
- * @throws IllegalStateException If the transaction is in a state where resources cannot be enlisted. This could be
- * because the transaction is no longer active, or because it is in the {@link
- * Status#STATUS_PREPARED prepared state}.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public boolean enlistResource(XAResource xaRes)
- throws RollbackException, IllegalStateException, SystemException {
- throw new SystemException("not supported");
- }
-
- /**
- * Delist an XA resource from this transaction.
- *
- * @return <code>true</code> if the resource could be delisted from this transaction, otherwise <code>false</code>.
- * @throws IllegalStateException If the transaction is in a state where resources cannot be delisted. This could be
- * because the transaction is no longer active.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public boolean delistResource(XAResource xaRes, int flag)
- throws IllegalStateException, SystemException {
- throw new SystemException("not supported");
- }
-
- /**
- * Register a {@link Synchronization} callback with this transaction.
- *
- * @throws RollbackException If the transaction is marked for rollback only.
- * @throws IllegalStateException If the transaction is in a state where {@link Synchronization} callbacks cannot be
- * registered. This could be because the transaction is no longer active, or because it
- * is in the {@link Status#STATUS_PREPARED prepared state}.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void registerSynchronization(Synchronization sync)
- throws RollbackException, IllegalStateException, SystemException {
- if (sync == null)
- throw new IllegalArgumentException("null synchronization " + this);
-
- switch (status) {
- case Status.STATUS_ACTIVE:
- case Status.STATUS_PREPARING:
- break;
- case Status.STATUS_PREPARED:
- throw new IllegalStateException("already prepared. " + this);
- case Status.STATUS_COMMITTING:
- throw new IllegalStateException("already started committing. " + this);
- case Status.STATUS_COMMITTED:
- throw new IllegalStateException("already committed. " + this);
- case Status.STATUS_MARKED_ROLLBACK:
- throw new RollbackException("already marked for rollback " + this);
- case Status.STATUS_ROLLING_BACK:
- throw new RollbackException("already started rolling back. " + this);
- case Status.STATUS_ROLLEDBACK:
- throw new RollbackException("already rolled back. " + this);
- case Status.STATUS_NO_TRANSACTION:
- throw new IllegalStateException("no transaction. " + this);
- case Status.STATUS_UNKNOWN:
- throw new IllegalStateException("unknown state " + this);
- default:
- throw new IllegalStateException("illegal status: " + status + " tx=" + this);
- }
-
- if (log.isDebugEnabled()) {
- log.debug("registering synchronization handler " + sync);
- }
- participants.add(sync);
-
- }
-
- void setStatus(int new_status) {
- status = new_status;
- }
-
- protected boolean notifyBeforeCompletion() {
- boolean retval = true;
-
- for (Synchronization s : participants) {
- if (log.isDebugEnabled()) {
- log.debug("processing beforeCompletion for " + s);
- }
- try {
- s.beforeCompletion();
- }
- catch (Throwable t) {
- retval = false;
- log.error("beforeCompletion() failed for " + s, t);
- }
- }
- return retval;
- }
-
- protected void notifyAfterCompletion(int status) {
- for (Synchronization s : participants) {
- if (log.isDebugEnabled()) {
- log.debug("processing afterCompletion for " + s);
- }
- try {
- s.afterCompletion(status);
- }
- catch (Throwable t) {
- log.error("afterCompletion() failed for " + s, t);
- }
- }
- participants.clear();
- }
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManager.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,89 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.naming.NoInitialContextException;
-import java.util.Properties;
-
-/**
- * Simple transaction manager implementation that maintains transaction state in memory only.
- *
- * @author bela
- * <p/>
- * Date: May 15, 2003 Time: 4:11:37 PM
- * @since 4.0
- */
-public class DummyTransactionManager extends DummyBaseTransactionManager {
- protected static DummyTransactionManager instance = null;
- protected static DummyUserTransaction utx = null;
-
- protected static Log log = LogFactory.getLog(DummyTransactionManager.class);
-
- private static final long serialVersionUID = 4396695354693176535L;
-
- public static DummyTransactionManager getInstance() {
- if (instance == null) {
- instance = new DummyTransactionManager();
- utx = new DummyUserTransaction(instance);
- try {
- Properties p = new Properties();
- Context ctx = new InitialContext(p);
- ctx.bind("java:/TransactionManager", instance);
- ctx.bind("UserTransaction", utx);
- } catch (NoInitialContextException nie) {
- log.debug(nie.getMessage());
-
- } catch (NamingException e) {
- log.debug("binding of DummyTransactionManager failed", e);
- }
- }
- return instance;
- }
-
- public static DummyUserTransaction getUserTransaction() {
- getInstance();
- return utx;
- }
-
- public static void destroy() {
- if (instance == null)
- return;
- try {
- Properties p = new Properties();
- Context ctx = new InitialContext(p);
- ctx.unbind("java:/TransactionManager");
- ctx.unbind("UserTransaction");
- }
- catch (NamingException e) {
- log.error("unbinding of DummyTransactionManager failed", e);
- }
- instance.setTransaction(null);
- instance = null;
- }
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManagerLookup.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManagerLookup.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,48 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-
-import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
-
-
-/**
- * Returns an instance of {@link org.infinispan.transaction.DummyTransactionManager}.
- *
- * @author Bela Ban Sept 5 2003
- * @since 4.0
- */
-public class DummyTransactionManagerLookup implements TransactionManagerLookup {
-
- public TransactionManager getTransactionManager() throws Exception {
- return DummyTransactionManager.getInstance();
- }
-
- public UserTransaction getUserTransaction() {
- return DummyTransactionManager.getUserTransaction();
- }
-
- public void cleanup() {
- DummyTransactionManager.destroy();
- }
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/DummyUserTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/DummyUserTransaction.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/DummyUserTransaction.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,130 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.UserTransaction;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author bela
- * <p/>
- * Date: May 15, 2003 Time: 4:20:17 PM
- * @since 4.0
- */
-public class DummyUserTransaction implements UserTransaction {
- static final Log logger_ = LogFactory.getLog(DummyUserTransaction.class);
- DummyTransactionManager tm_;
-
- /**
- * List<Synchronization>
- */
- List<Synchronization> l = new ArrayList<Synchronization>();
-
- public DummyUserTransaction(DummyTransactionManager tm) {
- tm_ = tm;
- }
-
-
- /**
- * Starts a new transaction, and associate it with the calling thread.
- *
- * @throws NotSupportedException If the calling thread is already associated with a transaction, and nested
- * transactions are not supported.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void begin() throws NotSupportedException, SystemException {
- tm_.begin();
- }
-
- /**
- * Attempt to commit this transaction.
- *
- * @throws RollbackException If the transaction was marked for rollback only, the transaction is rolled back
- * and this exception is thrown.
- * @throws SystemException If the transaction service fails in an unexpected way.
- * @throws HeuristicMixedException If a heuristic decision was made and some some parts of the transaction have
- * been committed while other parts have been rolled back.
- * @throws HeuristicRollbackException If a heuristic decision to roll back the transaction was made.
- * @throws SecurityException If the caller is not allowed to commit this transaction.
- */
- public void commit()
- throws RollbackException, HeuristicMixedException,
- HeuristicRollbackException, SecurityException, SystemException {
-
- tm_.commit();
- }
-
- /**
- * Rolls back this transaction.
- *
- * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
- * because the transaction is no longer active, or because it is in the {@link
- * Status#STATUS_PREPARED prepared state}.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void rollback() throws IllegalStateException, SystemException {
- tm_.rollback();
- }
-
- /**
- * Mark the transaction so that the only possible outcome is a rollback.
- *
- * @throws IllegalStateException If the transaction is not in an active state.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void setRollbackOnly() throws IllegalStateException, SystemException {
- tm_.setRollbackOnly();
- }
-
- /**
- * Get the status of the transaction.
- *
- * @return The status of the transaction. This is one of the {@link Status} constants.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public int getStatus() throws SystemException {
- return tm_.getStatus();
- }
-
- /**
- * Change the transaction timeout for transactions started by the calling thread with the {@link #begin()} method.
- *
- * @param seconds The new timeout value, in seconds. If this parameter is <code>0</code>, the timeout value is reset
- * to the default value.
- * @throws SystemException If the transaction service fails in an unexpected way.
- */
- public void setTransactionTimeout(int seconds) throws SystemException {
- throw new SystemException("not supported");
- }
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/GenericTransactionManagerLookup.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/GenericTransactionManagerLookup.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/GenericTransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,178 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.transaction.TransactionManager;
-import java.lang.reflect.Method;
-
-/**
- * A transaction manager lookup class that attempts to locate a TransactionManager. A variety of different classes and
- * JNDI locations are tried, for servers such as: <ul> <li> JBoss <li> JRun4 <li> Resin <li> Orion <li> JOnAS <li> BEA
- * Weblogic <li> Websphere 4.0, 5.0, 5.1, 6.0 <li> Sun, Glassfish </ul> If a transaction manager is not found, returns a
- * {@link org.infinispan.transaction.DummyTransactionManager}.
- *
- * @author Markus Plesser
- * @since 4.0
- */
-public class GenericTransactionManagerLookup implements TransactionManagerLookup {
-
- private static final Log log = LogFactory.getLog(GenericTransactionManagerLookup.class);
-
- /**
- * JNDI lookups performed?
- */
- private static boolean lookupDone = false;
-
- /**
- * No JNDI available?
- */
- private static boolean lookupFailed = false;
-
- /**
- * The JVM TransactionManager found.
- */
- private static TransactionManager tm = null;
-
- /**
- * JNDI locations for TransactionManagers we know of
- */
- private static String[][] knownJNDIManagers =
- {
- {"java:/TransactionManager", "JBoss, JRun4"},
- {"java:comp/TransactionManager", "Resin 3.x"},
- {"java:appserver/TransactionManager", "Sun Glassfish"},
- {"java:pm/TransactionManager", "Borland, Sun"},
- {"javax.transaction.TransactionManager", "BEA WebLogic"},
- {"java:comp/UserTransaction", "Resin, Orion, JOnAS (JOTM)"},
- };
-
- /**
- * WebSphere 5.1 and 6.0 TransactionManagerFactory
- */
- private static final String WS_FACTORY_CLASS_5_1 = "com.ibm.ws.Transaction.TransactionManagerFactory";
-
- /**
- * WebSphere 5.0 TransactionManagerFactory
- */
- private static final String WS_FACTORY_CLASS_5_0 = "com.ibm.ejs.jts.jta.TransactionManagerFactory";
-
- /**
- * WebSphere 4.0 TransactionManagerFactory
- */
- private static final String WS_FACTORY_CLASS_4 = "com.ibm.ejs.jts.jta.JTSXA";
-
- /**
- * Get the systemwide used TransactionManager
- *
- * @return TransactionManager
- */
- public TransactionManager getTransactionManager() {
- if (!lookupDone)
- doLookups();
- if (tm != null)
- return tm;
- if (lookupFailed) {
- //fall back to a dummy from Infinispan
- tm = DummyTransactionManager.getInstance();
- log.warn("Falling back to DummyTransactionManager from Infinispan");
- }
- return tm;
- }
-
- /**
- * Try to figure out which TransactionManager to use
- */
- private static void doLookups() {
- if (lookupFailed)
- return;
- InitialContext ctx;
- try {
- ctx = new InitialContext();
- }
- catch (NamingException e) {
- log.error("Failed creating initial JNDI context", e);
- lookupFailed = true;
- return;
- }
- //probe jndi lookups first
- for (String[] knownJNDIManager : knownJNDIManagers) {
- Object jndiObject;
- try {
- if (log.isDebugEnabled())
- log.debug("Trying to lookup TransactionManager for " + knownJNDIManager[1]);
- jndiObject = ctx.lookup(knownJNDIManager[0]);
- }
- catch (NamingException e) {
- log.debug("Failed to perform a lookup for [" + knownJNDIManager[0] + " (" + knownJNDIManager[1]
- + ")]");
- continue;
- }
- if (jndiObject instanceof TransactionManager) {
- tm = (TransactionManager) jndiObject;
- log.debug("Found TransactionManager for " + knownJNDIManager[1]);
- return;
- }
- }
- //try to find websphere lookups since we came here
- Class clazz;
- try {
- log.debug("Trying WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
- clazz = Class.forName(WS_FACTORY_CLASS_5_1);
- log.debug("Found WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
- }
- catch (ClassNotFoundException ex) {
- try {
- log.debug("Trying WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
- clazz = Class.forName(WS_FACTORY_CLASS_5_0);
- log.debug("Found WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
- }
- catch (ClassNotFoundException ex2) {
- try {
- log.debug("Trying WebSphere 4: " + WS_FACTORY_CLASS_4);
- clazz = Class.forName(WS_FACTORY_CLASS_4);
- log.debug("Found WebSphere 4: " + WS_FACTORY_CLASS_4);
- }
- catch (ClassNotFoundException ex3) {
- log.debug("Couldn't find any WebSphere TransactionManager factory class, neither for WebSphere version 5.1 nor 5.0 nor 4");
- lookupFailed = true;
- return;
- }
- }
- }
- try {
- Class[] signature = null;
- Object[] args = null;
- Method method = clazz.getMethod("getTransactionManager", signature);
- tm = (TransactionManager) method.invoke(null, args);
- }
- catch (Exception ex) {
- log.error("Found WebSphere TransactionManager factory class [" + clazz.getName()
- + "], but couldn't invoke its static 'getTransactionManager' method", ex);
- }
- }
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/GlobalTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/GlobalTransaction.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/GlobalTransaction.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,121 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.remoting.transport.Address;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-
-/**
- * Uniquely identifies a transaction that spans all JVMs in a cluster. This is used when replicating all modifications
- * in a transaction; the PREPARE and COMMIT (or ROLLBACK) messages have to have a unique identifier to associate the
- * changes with<br>
- *
- * @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 12, 2003
- * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- * @since 4.0
- */
-public class GlobalTransaction {
-
- private static AtomicLong sid = new AtomicLong(0);
-
- private Address addr = null;
- private long id = -1;
- private transient boolean remote = false;
-
- // cache the hashcode
- private transient int hash_code = -1; // in the worst case, hashCode() returns 0, then increases, so we're safe here
-
- /**
- * empty ctor used by externalization
- */
- public GlobalTransaction() {
- }
-
- private GlobalTransaction(Address addr) {
- this.addr = addr;
- id = sid.getAndIncrement();
- }
-
- public static GlobalTransaction create(Address addr) {
- return new GlobalTransaction(addr);
- }
-
- public Object getAddress() {
- return addr;
- }
-
- public void setAddress(Address address) {
- addr = address;
- }
-
- public long getId() {
- return id;
- }
-
- @Override
- public int hashCode() {
- if (hash_code == -1) {
- hash_code = (addr != null ? addr.hashCode() : 0) + (int) id;
- }
- return hash_code;
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other)
- return true;
- if (!(other instanceof GlobalTransaction))
- return false;
-
- GlobalTransaction otherGtx = (GlobalTransaction) other;
- boolean aeq = (addr == null) ? (otherGtx.addr == null) : addr.equals(otherGtx.addr);
- return aeq && (id == otherGtx.id);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("GlobalTransaction:<").append(addr).append(">:").append(id);
- return sb.toString();
- }
-
- /**
- * @return Returns the remote.
- */
- public boolean isRemote() {
- return remote;
- }
-
- /**
- * @param remote The remote to set.
- */
- public void setRemote(boolean remote) {
- this.remote = remote;
- }
-
-
- public void setId(long id) {
- this.id = id;
- }
-}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/transaction/JBossStandaloneJTAManagerLookup.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/JBossStandaloneJTAManagerLookup.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/JBossStandaloneJTAManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,55 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-
-import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
-import java.lang.reflect.Method;
-
-/**
- * JTA standalone TM lookup.
- *
- * @author Jason T. Greene
- * @since 4.0
- */
-public class JBossStandaloneJTAManagerLookup implements TransactionManagerLookup {
- private Method manager, user;
-
- public JBossStandaloneJTAManagerLookup() {
- try {
- manager = Class.forName("com.arjuna.ats.jta.TransactionManager").getMethod("transactionManager");
- user = Class.forName("com.arjuna.ats.jta.UserTransaction").getMethod("userTransaction");
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public TransactionManager getTransactionManager() throws Exception {
- return (TransactionManager) manager.invoke(null);
- }
-
- public UserTransaction getUserTransaction() throws Exception {
- return (UserTransaction) user.invoke(null);
- }
-}
\ No newline at end of file
Deleted: trunk/core/src/main/java/org/infinispan/transaction/JBossTransactionManagerLookup.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/JBossTransactionManagerLookup.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/JBossTransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,40 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import javax.naming.InitialContext;
-import javax.transaction.TransactionManager;
-
-
-/**
- * Uses JNDI to look-up the {@link TransactionManager} instance from "java:/TransactionManager".
- *
- * @author Bela Ban, Aug 26 2003
- * @since 4.0
- */
-public class JBossTransactionManagerLookup implements TransactionManagerLookup {
-
- public TransactionManager getTransactionManager() throws Exception {
- return (TransactionManager) new InitialContext().lookup("java:/TransactionManager");
- }
-
-}
Modified: trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -24,6 +24,7 @@
import org.infinispan.commands.tx.PrepareCommand;
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.marshall.Marshaller;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
Deleted: trunk/core/src/main/java/org/infinispan/transaction/TransactionManagerLookup.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/TransactionManagerLookup.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/TransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,45 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.Cache;
-import org.infinispan.config.Configuration;
-
-import javax.transaction.TransactionManager;
-
-/**
- * Factory interface, allows {@link Cache} to use different transactional systems. Names of implementors of this class
- * can be configured using {@link Configuration#setTransactionManagerLookupClass}.
- *
- * @author Bela Ban, Aug 26 2003
- * @since 4.0
- */
-public interface TransactionManagerLookup {
-
- /**
- * Returns a new TransactionManager.
- *
- * @throws Exception if lookup failed
- */
- TransactionManager getTransactionManager() throws Exception;
-
-}
Deleted: trunk/core/src/main/java/org/infinispan/transaction/TransactionTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/TransactionTable.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/transaction/TransactionTable.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,336 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.transaction;
-
-import org.infinispan.CacheException;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.TransactionContext;
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.factories.annotations.NonVolatile;
-import org.infinispan.factories.annotations.Start;
-import org.infinispan.factories.context.ContextFactory;
-import org.infinispan.remoting.RpcManager;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.remoting.transport.Transport;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Maintains the mapping between a local {@link Transaction} and a {@link GlobalTransaction}. Also stores {@link
- * TransactionContext} instances under a given transaction.
- *
- * @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 14, 2003
- * @since 4.0
- */
- at NonVolatile
-public class TransactionTable {
- private static final Log log = LogFactory.getLog(TransactionTable.class);
- private static final boolean trace = log.isTraceEnabled();
-
- /**
- * Mapping between local (javax.transaction.Transaction) and a TransactionContext
- */
- protected final Map<Transaction, TransactionContext> txMapping = new ConcurrentHashMap<Transaction, TransactionContext>();
-
- /**
- * Mappong between GlobalTransaction and a TransactionContext
- */
- protected final Map<GlobalTransaction, TransactionContext> gtxMapping = new ConcurrentHashMap<GlobalTransaction, TransactionContext>();
-
- private TransactionManager transactionManager = null;
-
- private RpcManager rpcManager;
- private Transport transport;
-
- private ContextFactory contextFactory;
-
- @Inject
- public void initialize(TransactionManager transactionManager, RpcManager rpcManager, ContextFactory contextFactory) {
- this.transactionManager = transactionManager;
- this.rpcManager = rpcManager;
- this.contextFactory = contextFactory;
- }
-
- @Start(priority = 12)
- // needs to happen after RpcManager
- public void start() {
- transport = rpcManager == null ? null : rpcManager.getTransport();
- }
-
-
- /**
- * Returns the number of local transactions.
- */
- public int getNumLocalTransactions() {
- return txMapping.size();
- }
-
- /**
- * Returns the number of global transactions.
- */
- public int getNumGlobalTransactions() {
- return txMapping.size();
- }
-
- /**
- * Returns the global transaction associated with the local transaction. Returns null if tx is null or it was not
- * found.
- */
- public GlobalTransaction get(Transaction tx) {
- if (tx == null) return null;
- TransactionContext ctx = txMapping.get(tx);
- return ctx == null ? null : ctx.getGobalTransaction();
- }
-
- /**
- * If assers exists is true and the coresponding local transaction is null an IllegalStateExcetpion is being thrown.
- */
- public Transaction getLocalTransaction(GlobalTransaction gtx, boolean assertExists) {
- Transaction ltx = getLocalTransaction(gtx);
- if (!assertExists) {
- return ltx;
- }
- if (ltx != null) {
- if (log.isDebugEnabled()) log.debug("Found local TX=" + ltx + ", global TX=" + gtx);
- return ltx;
- } else {
- throw new IllegalStateException(" found no local TX for global TX " + gtx);
- }
- }
-
- /**
- * Associates 3 elements of a transaction - a local Transaction, a GlobalTransaction and a TransactionContext - with
- * each other.
- *
- * @param tx transaction to associate
- * @param gtx global transaction to associate
- * @param ctx transaction context to associate
- */
- public void associateTransaction(Transaction tx, GlobalTransaction gtx, TransactionContext ctx) {
- if (ctx.getTransaction() == null) ctx.setTransaction(tx);
- if (ctx.getGobalTransaction() == null) ctx.setGlobalTransaction(gtx);
-
- txMapping.put(tx, ctx);
- gtxMapping.put(gtx, ctx);
- }
-
- public Transaction getLocalTransaction(GlobalTransaction gtx) {
- TransactionContext ctx = gtxMapping.get(gtx);
- return ctx == null ? null : ctx.getTransaction();
- }
-
- /**
- * Returns summary debug information.
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(txMapping.size()).append(" transactions");
- return sb.toString();
- }
-
- /**
- * Returns detailed debug information.
- */
- public String toString(boolean printDetails) {
- if (!printDetails)
- return toString();
- StringBuilder sb = new StringBuilder();
- sb.append("Transactions: ").append(txMapping.size()).append("\n");
- sb.append("mappings:\n");
- for (Map.Entry<Transaction, TransactionContext> entry : txMapping.entrySet()) {
- sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
- }
- return sb.toString();
- }
-
- /**
- * Returns the transaction associated with the current thread. If a local transaction exists, but doesn't yet have a
- * mapping to a GlobalTransaction, a new GlobalTransaction will be created and mapped to the local transaction. Note
- * that if a local transaction exists, but is not ACTIVE or PREPARING, null is returned.
- *
- * @return A GlobalTransaction, or null if no (local) transaction was associated with the current thread
- */
- public GlobalTransaction getCurrentTransaction() {
- return getCurrentTransaction(true);
- }
-
-
- /**
- * Returns the transaction associated with the thread; optionally creating it if is does not exist.
- */
- public GlobalTransaction getCurrentTransaction(boolean createIfNotExists) {
- Transaction tx;
-
- if ((tx = getLocalTransaction()) == null) {// no transaction is associated with the current thread
- return null;
- }
-
- if (!isValid(tx)) {// we got a non-null transaction, but it is not active anymore
- int status = -1;
- try {
- status = tx.getStatus();
- }
- catch (SystemException e) {
- }
-
- // JBCACHE-982 -- don't complain if COMMITTED
- if (status != Status.STATUS_COMMITTED) {
- log.warn("status is " + status + " (not ACTIVE or PREPARING); returning null)");
- } else {
- log.trace("status is COMMITTED; returning null");
- }
-
- return null;
- }
-
- return getCurrentTransaction(tx, createIfNotExists);
- }
-
- /**
- * Returns the transaction associated with the current thread. We get the initial context and a reference to the
- * TransactionManager to get the transaction. This method is used by {@link #getCurrentTransaction()}
- */
- protected Transaction getLocalTransaction() {
- if (transactionManager == null) {
- return null;
- }
- try {
- return transactionManager.getTransaction();
- }
- catch (Throwable t) {
- return null;
- }
- }
-
- /**
- * Returns true if transaction is ACTIVE, false otherwise
- */
- public static boolean isActive(Transaction tx) {
- if (tx == null) return false;
- int status;
- try {
- status = tx.getStatus();
- return status == Status.STATUS_ACTIVE;
- }
- catch (SystemException e) {
- return false;
- }
- }
-
- /**
- * Returns true if transaction is PREPARING, false otherwise
- */
- public static boolean isPreparing(Transaction tx) {
- if (tx == null) return false;
- int status;
- try {
- status = tx.getStatus();
- return status == Status.STATUS_PREPARING;
- }
- catch (SystemException e) {
- return false;
- }
- }
-
- /**
- * Return s true of tx's status is ACTIVE or PREPARING
- *
- * @param tx
- * @return true if the tx is active or preparing
- */
- public static boolean isValid(Transaction tx) {
- return isActive(tx) || isPreparing(tx);
- }
-
- /**
- * Tests whether the caller is in a valid transaction. If not, will throw a CacheException.
- */
- public static void assertTransactionValid(InvocationContext ctx) {
- Transaction tx = ctx.getTransaction();
- if (!isValid(tx)) try {
- throw new CacheException("Invalid transaction " + tx + ", status = " + (tx == null ? null : tx.getStatus()));
- }
- catch (SystemException e) {
- throw new CacheException("Exception trying to analyse status of transaction " + tx, e);
- }
- }
-
-
- /**
- * Returns the global transaction for this local transaction.
- */
- public GlobalTransaction getCurrentTransaction(Transaction tx) {
- return getCurrentTransaction(tx, true);
- }
-
- /**
- * Returns the global transaction for this local transaction.
- *
- * @param createIfNotExists if true, if a global transaction is not found; one is created
- */
- public GlobalTransaction getCurrentTransaction(Transaction tx, boolean createIfNotExists) {
- // removed synchronization on txTable because underlying implementation is thread safe
- // and JTA spec (section 3.4.3 Thread of Control, par 2) says that only one thread may
- // operate on the transaction at one time so no concern about 2 threads trying to call
- // this method for the same Transaction instance at the same time
- //
- GlobalTransaction gtx = get(tx);
- if (gtx == null && createIfNotExists) {
- Address addr = getAddress();
- gtx = GlobalTransaction.create(addr);
- if (trace) log.trace("Creating new GlobalTransaction " + gtx);
- TransactionContext transactionContext;
- try {
- transactionContext = contextFactory.createTransactionContext(tx);
- }
- catch (Exception e) {
- throw new CacheException("Unable to create a transaction entry!", e);
- }
- associateTransaction(tx, gtx, transactionContext);
- if (trace) {
- log.trace("created new GTX: " + gtx + ", local TX=" + tx);
- }
- }
- return gtx;
- }
-
- private Address getAddress() {
- return transport == null ? null : transport.getAddress();
- }
-
- public TransactionContext getTransactionContext(GlobalTransaction gtx) {
- return gtxMapping.get(gtx);
- }
-
- public void cleanup(GlobalTransaction gtx) {
- TransactionContext ctx = gtxMapping.remove(gtx);
- if (ctx != null) txMapping.remove(ctx.getTransaction());
- }
-}
Copied: trunk/core/src/main/java/org/infinispan/transaction/lookup/DummyTransactionManagerLookup.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManagerLookup.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/lookup/DummyTransactionManagerLookup.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/lookup/DummyTransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,50 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.lookup;
+
+
+import org.infinispan.transaction.tm.DummyTransactionManager;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+
+/**
+ * Returns an instance of {@link org.infinispan.transaction.tm.DummyTransactionManager}.
+ *
+ * @author Bela Ban Sept 5 2003
+ * @since 4.0
+ */
+public class DummyTransactionManagerLookup implements TransactionManagerLookup {
+
+ public TransactionManager getTransactionManager() throws Exception {
+ return DummyTransactionManager.getInstance();
+ }
+
+ public UserTransaction getUserTransaction() {
+ return DummyTransactionManager.getUserTransaction();
+ }
+
+ public void cleanup() {
+ DummyTransactionManager.destroy();
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/lookup/DummyTransactionManagerLookup.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/lookup/GenericTransactionManagerLookup.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/GenericTransactionManagerLookup.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/lookup/GenericTransactionManagerLookup.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/lookup/GenericTransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,179 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.lookup;
+
+import org.infinispan.transaction.tm.DummyTransactionManager;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.transaction.TransactionManager;
+import java.lang.reflect.Method;
+
+/**
+ * A transaction manager lookup class that attempts to locate a TransactionManager. A variety of different classes and
+ * JNDI locations are tried, for servers such as: <ul> <li> JBoss <li> JRun4 <li> Resin <li> Orion <li> JOnAS <li> BEA
+ * Weblogic <li> Websphere 4.0, 5.0, 5.1, 6.0 <li> Sun, Glassfish </ul> If a transaction manager is not found, returns a
+ * {@link org.infinispan.transaction.tm.DummyTransactionManager}.
+ *
+ * @author Markus Plesser
+ * @since 4.0
+ */
+public class GenericTransactionManagerLookup implements TransactionManagerLookup {
+
+ private static final Log log = LogFactory.getLog(GenericTransactionManagerLookup.class);
+
+ /**
+ * JNDI lookups performed?
+ */
+ private static boolean lookupDone = false;
+
+ /**
+ * No JNDI available?
+ */
+ private static boolean lookupFailed = false;
+
+ /**
+ * The JVM TransactionManager found.
+ */
+ private static TransactionManager tm = null;
+
+ /**
+ * JNDI locations for TransactionManagers we know of
+ */
+ private static String[][] knownJNDIManagers =
+ {
+ {"java:/TransactionManager", "JBoss, JRun4"},
+ {"java:comp/TransactionManager", "Resin 3.x"},
+ {"java:appserver/TransactionManager", "Sun Glassfish"},
+ {"java:pm/TransactionManager", "Borland, Sun"},
+ {"javax.transaction.TransactionManager", "BEA WebLogic"},
+ {"java:comp/UserTransaction", "Resin, Orion, JOnAS (JOTM)"},
+ };
+
+ /**
+ * WebSphere 5.1 and 6.0 TransactionManagerFactory
+ */
+ private static final String WS_FACTORY_CLASS_5_1 = "com.ibm.ws.Transaction.TransactionManagerFactory";
+
+ /**
+ * WebSphere 5.0 TransactionManagerFactory
+ */
+ private static final String WS_FACTORY_CLASS_5_0 = "com.ibm.ejs.jts.jta.TransactionManagerFactory";
+
+ /**
+ * WebSphere 4.0 TransactionManagerFactory
+ */
+ private static final String WS_FACTORY_CLASS_4 = "com.ibm.ejs.jts.jta.JTSXA";
+
+ /**
+ * Get the systemwide used TransactionManager
+ *
+ * @return TransactionManager
+ */
+ public TransactionManager getTransactionManager() {
+ if (!lookupDone)
+ doLookups();
+ if (tm != null)
+ return tm;
+ if (lookupFailed) {
+ //fall back to a dummy from Infinispan
+ tm = DummyTransactionManager.getInstance();
+ log.warn("Falling back to DummyTransactionManager from Infinispan");
+ }
+ return tm;
+ }
+
+ /**
+ * Try to figure out which TransactionManager to use
+ */
+ private static void doLookups() {
+ if (lookupFailed)
+ return;
+ InitialContext ctx;
+ try {
+ ctx = new InitialContext();
+ }
+ catch (NamingException e) {
+ log.error("Failed creating initial JNDI context", e);
+ lookupFailed = true;
+ return;
+ }
+ //probe jndi lookups first
+ for (String[] knownJNDIManager : knownJNDIManagers) {
+ Object jndiObject;
+ try {
+ if (log.isDebugEnabled())
+ log.debug("Trying to lookup TransactionManager for " + knownJNDIManager[1]);
+ jndiObject = ctx.lookup(knownJNDIManager[0]);
+ }
+ catch (NamingException e) {
+ log.debug("Failed to perform a lookup for [" + knownJNDIManager[0] + " (" + knownJNDIManager[1]
+ + ")]");
+ continue;
+ }
+ if (jndiObject instanceof TransactionManager) {
+ tm = (TransactionManager) jndiObject;
+ log.debug("Found TransactionManager for " + knownJNDIManager[1]);
+ return;
+ }
+ }
+ //try to find websphere lookups since we came here
+ Class clazz;
+ try {
+ log.debug("Trying WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
+ clazz = Class.forName(WS_FACTORY_CLASS_5_1);
+ log.debug("Found WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
+ }
+ catch (ClassNotFoundException ex) {
+ try {
+ log.debug("Trying WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
+ clazz = Class.forName(WS_FACTORY_CLASS_5_0);
+ log.debug("Found WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
+ }
+ catch (ClassNotFoundException ex2) {
+ try {
+ log.debug("Trying WebSphere 4: " + WS_FACTORY_CLASS_4);
+ clazz = Class.forName(WS_FACTORY_CLASS_4);
+ log.debug("Found WebSphere 4: " + WS_FACTORY_CLASS_4);
+ }
+ catch (ClassNotFoundException ex3) {
+ log.debug("Couldn't find any WebSphere TransactionManager factory class, neither for WebSphere version 5.1 nor 5.0 nor 4");
+ lookupFailed = true;
+ return;
+ }
+ }
+ }
+ try {
+ Class[] signature = null;
+ Object[] args = null;
+ Method method = clazz.getMethod("getTransactionManager", signature);
+ tm = (TransactionManager) method.invoke(null, args);
+ }
+ catch (Exception ex) {
+ log.error("Found WebSphere TransactionManager factory class [" + clazz.getName()
+ + "], but couldn't invoke its static 'getTransactionManager' method", ex);
+ }
+ }
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/lookup/GenericTransactionManagerLookup.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossStandaloneJTAManagerLookup.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/JBossStandaloneJTAManagerLookup.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossStandaloneJTAManagerLookup.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossStandaloneJTAManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.lookup;
+
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.lang.reflect.Method;
+
+/**
+ * JTA standalone TM lookup.
+ *
+ * @author Jason T. Greene
+ * @since 4.0
+ */
+public class JBossStandaloneJTAManagerLookup implements TransactionManagerLookup {
+ private Method manager, user;
+
+ public JBossStandaloneJTAManagerLookup() {
+ try {
+ manager = Class.forName("com.arjuna.ats.jta.TransactionManager").getMethod("transactionManager");
+ user = Class.forName("com.arjuna.ats.jta.UserTransaction").getMethod("userTransaction");
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public TransactionManager getTransactionManager() throws Exception {
+ return (TransactionManager) manager.invoke(null);
+ }
+
+ public UserTransaction getUserTransaction() throws Exception {
+ return (UserTransaction) user.invoke(null);
+ }
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossStandaloneJTAManagerLookup.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossTransactionManagerLookup.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/JBossTransactionManagerLookup.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossTransactionManagerLookup.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossTransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.lookup;
+
+import javax.naming.InitialContext;
+import javax.transaction.TransactionManager;
+
+
+/**
+ * Uses JNDI to look-up the {@link TransactionManager} instance from "java:/TransactionManager".
+ *
+ * @author Bela Ban, Aug 26 2003
+ * @since 4.0
+ */
+public class JBossTransactionManagerLookup implements TransactionManagerLookup {
+
+ public TransactionManager getTransactionManager() throws Exception {
+ return (TransactionManager) new InitialContext().lookup("java:/TransactionManager");
+ }
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/lookup/JBossTransactionManagerLookup.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/lookup/TransactionManagerLookup.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/TransactionManagerLookup.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/lookup/TransactionManagerLookup.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/lookup/TransactionManagerLookup.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.lookup;
+
+import javax.transaction.TransactionManager;
+
+/**
+ * Factory interface, allows {@link org.infinispan.Cache} to use different transactional systems. Names of implementors of
+ * this class can be configured using {@link Configuration#setTransactionManagerLookupClass}.
+ *
+ * @author Bela Ban, Aug 26 2003
+ * @since 4.0
+ */
+public interface TransactionManagerLookup {
+
+ /**
+ * Returns a new TransactionManager.
+ *
+ * @throws Exception if lookup failed
+ */
+ TransactionManager getTransactionManager() throws Exception;
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/lookup/TransactionManagerLookup.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/tm/BatchModeTransactionManager.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/BatchModeTransactionManager.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/tm/BatchModeTransactionManager.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/tm/BatchModeTransactionManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.tm;
+
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+/**
+ * Not really a transaction manager in the truest sense of the word. Only used to batch up operations. Proper
+ * transactional symantics of rollbacks and recovery are NOT used here.
+ *
+ * @author bela
+ * <p/>
+ * Date: May 15, 2003 Time: 4:11:37 PM
+ * @since 4.0
+ */
+public class BatchModeTransactionManager extends DummyBaseTransactionManager {
+ static BatchModeTransactionManager instance = null;
+ static Log log = LogFactory.getLog(BatchModeTransactionManager.class);
+ private static final long serialVersionUID = 5656602677430350961L;
+
+ public static BatchModeTransactionManager getInstance() {
+ if (instance == null) {
+ instance = new BatchModeTransactionManager();
+ }
+ return instance;
+ }
+
+ public static void destroy() {
+ if (instance == null) return;
+ instance.setTransaction(null);
+ instance = null;
+ }
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/tm/BatchModeTransactionManager.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyBaseTransactionManager.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/DummyBaseTransactionManager.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/tm/DummyBaseTransactionManager.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/tm/DummyBaseTransactionManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,218 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.tm;
+
+
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.io.Serializable;
+
+/**
+ * @author bela
+ * @since 4.0
+ */
+public class DummyBaseTransactionManager implements TransactionManager, Serializable {
+ static ThreadLocal<DummyTransaction> thread_local = new ThreadLocal<DummyTransaction>();
+ private static final long serialVersionUID = -6716097342564237376l;
+ private static final Log log = LogFactory.getLog(DummyBaseTransactionManager.class);
+ private static final boolean trace = log.isTraceEnabled();
+
+ /**
+ * Starts a new transaction, and associate it with the calling thread.
+ *
+ * @throws javax.transaction.NotSupportedException
+ * If the calling thread is already associated with a transaction, and nested transactions are not
+ * supported.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public void begin() throws NotSupportedException, SystemException {
+ Transaction currentTx;
+ if ((currentTx = getTransaction()) != null)
+ throw new NotSupportedException(Thread.currentThread() +
+ " is already associated with a transaction (" + currentTx + ")");
+ DummyTransaction tx = new DummyTransaction(this);
+ setTransaction(tx);
+ }
+
+ /**
+ * Commit the transaction associated with the calling thread.
+ *
+ * @throws javax.transaction.RollbackException
+ * If the transaction was marked for rollback only, the transaction is rolled back and
+ * this exception is thrown.
+ * @throws IllegalStateException If the calling thread is not associated with a transaction.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ * @throws javax.transaction.HeuristicMixedException
+ * If a heuristic decision was made and some some parts of the transaction have been
+ * committed while other parts have been rolled back.
+ * @throws javax.transaction.HeuristicRollbackException
+ * If a heuristic decision to roll back the transaction was made.
+ * @throws SecurityException If the caller is not allowed to commit this transaction.
+ */
+ public void commit() throws RollbackException, HeuristicMixedException,
+ HeuristicRollbackException, SecurityException,
+ IllegalStateException, SystemException {
+ int status;
+ DummyTransaction tx = getTransaction();
+ if (tx == null)
+ throw new IllegalStateException("thread not associated with transaction");
+ status = tx.getStatus();
+ if (status == Status.STATUS_MARKED_ROLLBACK) {
+ tx.setStatus(Status.STATUS_ROLLEDBACK);
+ rollback();
+ throw new RollbackException("Transaction status is Status.STATUS_MARKED_ROLLBACK");
+ } else {
+ tx.commit();
+ }
+
+ // Disassociate tx from thread.
+ setTransaction(null);
+ }
+
+ /**
+ * Rolls back the transaction associated with the calling thread.
+ *
+ * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
+ * because the calling thread is not associated with a transaction, or because it is in
+ * the {@link javax.transaction.Status#STATUS_PREPARED prepared state}.
+ * @throws SecurityException If the caller is not allowed to roll back this transaction.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public void rollback() throws IllegalStateException, SecurityException,
+ SystemException {
+ Transaction tx = getTransaction();
+ if (tx == null)
+ throw new IllegalStateException("no transaction associated with thread");
+ tx.rollback();
+
+ // Disassociate tx from thread.
+ setTransaction(null);
+ }
+
+ /**
+ * Mark the transaction associated with the calling thread for rollback only.
+ *
+ * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
+ * because the calling thread is not associated with a transaction, or because it is in
+ * the {@link javax.transaction.Status#STATUS_PREPARED prepared state}.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException {
+ Transaction tx = getTransaction();
+ if (tx == null)
+ throw new IllegalStateException("no transaction associated with calling thread");
+ tx.setRollbackOnly();
+ }
+
+ /**
+ * Get the status of the transaction associated with the calling thread.
+ *
+ * @return The status of the transaction. This is one of the {@link javax.transaction.Status} constants. If no
+ * transaction is associated with the calling thread, {@link javax.transaction.Status#STATUS_NO_TRANSACTION}
+ * is returned.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public int getStatus() throws SystemException {
+ Transaction tx = getTransaction();
+ return tx != null ? tx.getStatus() : Status.STATUS_NO_TRANSACTION;
+ }
+
+ /**
+ * Get the transaction associated with the calling thread.
+ *
+ * @return The transaction associated with the calling thread, or <code>null</code> if the calling thread is not
+ * associated with a transaction.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public DummyTransaction getTransaction() {
+ return thread_local.get();
+ }
+
+ /**
+ * Change the transaction timeout for transactions started by the calling thread with the {@link #begin()} method.
+ *
+ * @param seconds The new timeout value, in seconds. If this parameter is <code>0</code>, the timeout value is reset
+ * to the default value.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public void setTransactionTimeout(int seconds) throws SystemException {
+ throw new SystemException("not supported");
+ }
+
+ /**
+ * Suspend the association the calling thread has to a transaction, and return the suspended transaction. When
+ * returning from this method, the calling thread is no longer associated with a transaction.
+ *
+ * @return The transaction that the calling thread was associated with, or <code>null</code> if the calling thread
+ * was not associated with a transaction.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public Transaction suspend() throws SystemException {
+ Transaction retval = getTransaction();
+ setTransaction(null);
+ if (trace) log.trace("Suspending tx " + retval);
+ return retval;
+ }
+
+ /**
+ * Resume the association of the calling thread with the given transaction.
+ *
+ * @param tx The transaction to be associated with the calling thread.
+ * @throws javax.transaction.InvalidTransactionException
+ * If the argument does not represent a valid transaction.
+ * @throws IllegalStateException If the calling thread is already associated with a transaction.
+ * @throws javax.transaction.SystemException
+ * If the transaction service fails in an unexpected way.
+ */
+ public void resume(Transaction tx) throws InvalidTransactionException, IllegalStateException, SystemException {
+ if (trace) log.trace("Resuming tx " + tx);
+ setTransaction(tx);
+ }
+
+ /**
+ * Just used for unit tests
+ *
+ * @param tx
+ */
+ public void setTransaction(Transaction tx) {
+ thread_local.set((DummyTransaction) tx);
+ }
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyBaseTransactionManager.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransaction.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/DummyTransaction.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransaction.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransaction.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,333 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.tm;
+
+
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author bela
+ * @since 4.0
+ */
+public class DummyTransaction implements Transaction {
+ private volatile int status = Status.STATUS_UNKNOWN;
+ private static final Log log = LogFactory.getLog(DummyTransaction.class);
+ protected DummyBaseTransactionManager tm_;
+ protected DummyXid xid = new DummyXid();
+
+ protected Set<Synchronization> syncs;
+ private List<XAResource> enlistedResources = new ArrayList<XAResource>();
+
+ public DummyTransaction(DummyBaseTransactionManager tm) {
+ tm_ = tm;
+ status = Status.STATUS_ACTIVE;
+ }
+
+ /**
+ * Attempt to commit this transaction.
+ *
+ * @throws RollbackException If the transaction was marked for rollback only, the transaction is rolled back
+ * and this exception is thrown.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ * @throws HeuristicMixedException If a heuristic decision was made and some some parts of the transaction have
+ * been committed while other parts have been rolled back.
+ * @throws HeuristicRollbackException If a heuristic decision to roll back the transaction was made.
+ * @throws SecurityException If the caller is not allowed to commit this transaction.
+ */
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, SystemException {
+ try {
+ if (!notifyBeforeCompletion()) {
+ log.trace("Not running 2PC as Synchronization.before not successfull");
+ return;
+ }
+
+ //1) run prepare first
+ status = Status.STATUS_PREPARING;
+ if (!runPrepare()) {
+ status = Status.STATUS_ROLLING_BACK;
+ } else {
+ status = Status.STATUS_PREPARED;
+ }
+
+ //2) shall we rollback?
+ if (status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLING_BACK) {
+ runRollback();
+ throw new RollbackException("Exception rollbacked, status is: " + status);
+ }
+
+ //3) if we reached this point then we shall go on and commit
+ try {
+ status = Status.STATUS_COMMITTING;
+ runCommitTx();
+ status = Status.STATUS_COMMITTED;
+ } catch (HeuristicMixedException e) {
+ status = Status.STATUS_UNKNOWN;
+ } finally {
+ //notify syncronizations
+ notifyAfterCompletion(status);
+ }
+ }
+ finally {
+ // Disassociate tx from thread.
+ tm_.setTransaction(null);
+ }
+ }
+
+ /**
+ * Rolls back this transaction.
+ *
+ * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
+ * because the transaction is no longer active, or because it is in the {@link
+ * Status#STATUS_PREPARED prepared state}.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void rollback() throws IllegalStateException, SystemException {
+ try {
+ // JBCACHE-360 -- to match JBossTM (and presumable the spec) a
+ // rollback transaction should have status ROLLEDBACK before
+ // calling afterCompletion().
+ //status=Status.STATUS_ROLLING_BACK;
+ status = Status.STATUS_ROLLING_BACK;
+ runRollback();
+ status = Status.STATUS_ROLLEDBACK;
+ notifyAfterCompletion(Status.STATUS_ROLLEDBACK);
+ }
+ catch (Throwable t) {
+ log.error(t);
+ throw new IllegalStateException(t);
+ }
+ // Disassociate tx from thread.
+ tm_.setTransaction(null);
+ }
+
+ /**
+ * Mark the transaction so that the only possible outcome is a rollback.
+ *
+ * @throws IllegalStateException If the transaction is not in an active state.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException {
+ status = Status.STATUS_MARKED_ROLLBACK;
+ }
+
+ /**
+ * Get the status of the transaction.
+ *
+ * @return The status of the transaction. This is one of the {@link Status} constants.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public int getStatus() throws SystemException {
+ return status;
+ }
+
+ /**
+ * Change the transaction timeout for transactions started by the calling thread with the {@link
+ * DummyTransactionManager#begin()} method.
+ *
+ * @param seconds The new timeout value, in seconds. If this parameter is <code>0</code>, the timeout value is reset
+ * to the default value.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void setTransactionTimeout(int seconds) throws SystemException {
+ throw new SystemException("not supported");
+ }
+
+ /**
+ * Enlist an XA resource with this transaction.
+ *
+ * @return <code>true</code> if the resource could be enlisted with this transaction, otherwise <code>false</code>.
+ * @throws RollbackException If the transaction is marked for rollback only.
+ * @throws IllegalStateException If the transaction is in a state where resources cannot be enlisted. This could be
+ * because the transaction is no longer active, or because it is in the {@link
+ * Status#STATUS_PREPARED prepared state}.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public boolean enlistResource(XAResource xaRes) throws RollbackException, IllegalStateException, SystemException {
+ this.enlistedResources.add(xaRes);
+ try {
+ xaRes.start(xid, 0);
+ } catch (XAException e) {
+ log.error(e);
+ throw new SystemException(e.getMessage());
+ }
+ return true;
+ }
+
+ /**
+ * Delist an XA resource from this transaction.
+ *
+ * @return <code>true</code> if the resource could be delisted from this transaction, otherwise <code>false</code>.
+ * @throws IllegalStateException If the transaction is in a state where resources cannot be delisted. This could be
+ * because the transaction is no longer active.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public boolean delistResource(XAResource xaRes, int flag)
+ throws IllegalStateException, SystemException {
+ throw new SystemException("not supported");
+ }
+
+ /**
+ * Register a {@link Synchronization} callback with this transaction.
+ *
+ * @throws RollbackException If the transaction is marked for rollback only.
+ * @throws IllegalStateException If the transaction is in a state where {@link Synchronization} callbacks cannot be
+ * registered. This could be because the transaction is no longer active, or because it
+ * is in the {@link Status#STATUS_PREPARED prepared state}.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void registerSynchronization(Synchronization sync) throws RollbackException, IllegalStateException, SystemException {
+ if (sync == null)
+ throw new IllegalArgumentException("null synchronization " + this);
+ if (syncs == null) syncs = new HashSet<Synchronization>(8);
+
+ switch (status) {
+ case Status.STATUS_ACTIVE:
+ case Status.STATUS_PREPARING:
+ break;
+ case Status.STATUS_PREPARED:
+ throw new IllegalStateException("already prepared. " + this);
+ case Status.STATUS_COMMITTING:
+ throw new IllegalStateException("already started committing. " + this);
+ case Status.STATUS_COMMITTED:
+ throw new IllegalStateException("already committed. " + this);
+ case Status.STATUS_MARKED_ROLLBACK:
+ throw new RollbackException("already marked for rollback " + this);
+ case Status.STATUS_ROLLING_BACK:
+ throw new RollbackException("already started rolling back. " + this);
+ case Status.STATUS_ROLLEDBACK:
+ throw new RollbackException("already rolled back. " + this);
+ case Status.STATUS_NO_TRANSACTION:
+ throw new IllegalStateException("no transaction. " + this);
+ case Status.STATUS_UNKNOWN:
+ throw new IllegalStateException("unknown state " + this);
+ default:
+ throw new IllegalStateException("illegal status: " + status + " tx=" + this);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("registering synchronization handler " + sync);
+ }
+ syncs.add(sync);
+
+ }
+
+ protected boolean notifyBeforeCompletion() throws SystemException {
+ boolean retval = true;
+ if (syncs == null) return true;
+ for (Synchronization s : syncs) {
+ if (log.isDebugEnabled()) {
+ log.debug("processing beforeCompletion for " + s);
+ }
+ try {
+ s.beforeCompletion();
+ }
+ catch (Throwable t) {
+ retval = false;
+ log.error("beforeCompletion() failed for " + s, t);
+ }
+ }
+ return retval;
+ }
+
+ private boolean runPrepare() throws SystemException {
+ DummyTransaction transaction = tm_.getTransaction();
+ Collection<XAResource> resources = transaction.getEnlistedResources();
+ for (XAResource res : resources) {
+ try {
+ res.prepare(xid);
+ } catch (XAException e) {
+ log.trace("The resource wants to rollback!", e);
+ return false;
+ } catch (Throwable th) {
+ log.error("Unexpected error from resource manager!", th);
+ throw new SystemException(th.getMessage());
+ }
+ }
+ return true;
+ }
+
+ protected void notifyAfterCompletion(int status) {
+ if (syncs == null) return;
+ for (Synchronization s : syncs) {
+ if (log.isDebugEnabled()) {
+ log.debug("processing afterCompletion for " + s);
+ }
+ try {
+ s.afterCompletion(status);
+ }
+ catch (Throwable t) {
+ log.error("afterCompletion() failed for " + s, t);
+ }
+ }
+ syncs.clear();
+ }
+
+ public Collection<XAResource> getEnlistedResources() {
+ return enlistedResources;
+ }
+
+ private void runRollback() {
+ DummyTransaction transaction = tm_.getTransaction();
+ Collection<XAResource> resources = transaction.getEnlistedResources();
+ for (XAResource res : resources) {
+ try {
+ res.rollback(xid);
+ } catch (XAException e) {
+ log.warn("Error while rolling back",e);
+ }
+ }
+ }
+
+ private boolean runCommitTx() throws HeuristicMixedException {
+ DummyTransaction transaction = tm_.getTransaction();
+ Collection<XAResource> resources = transaction.getEnlistedResources();
+ for (XAResource res : resources) {
+ try {
+ res.commit(xid, false);//todo we only support one phase commit for now, change this!!!
+ } catch (XAException e) {
+ log.warn("exception while committing",e);
+ throw new HeuristicMixedException(e.getMessage());
+ }
+ }
+ return true;
+ }
+
+ public void setStatus(int stat) {
+ this.status = stat;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransaction.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransactionManager.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/DummyTransactionManager.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransactionManager.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransactionManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.tm;
+
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.NoInitialContextException;
+import java.util.Properties;
+
+/**
+ * Simple transaction manager implementation that maintains transaction state in memory only.
+ *
+ * @author bela
+ * <p/>
+ * Date: May 15, 2003 Time: 4:11:37 PM
+ * @since 4.0
+ */
+public class DummyTransactionManager extends DummyBaseTransactionManager {
+ protected static DummyTransactionManager instance = null;
+ protected static DummyUserTransaction utx = null;
+
+ protected static Log log = LogFactory.getLog(DummyTransactionManager.class);
+
+ private static final long serialVersionUID = 4396695354693176535L;
+
+ public static DummyTransactionManager getInstance() {
+ if (instance == null) {
+ instance = new DummyTransactionManager();
+ utx = new DummyUserTransaction(instance);
+ try {
+ Properties p = new Properties();
+ Context ctx = new InitialContext(p);
+ ctx.bind("java:/TransactionManager", instance);
+ ctx.bind("UserTransaction", utx);
+ } catch (NoInitialContextException nie) {
+ log.debug(nie.getMessage());
+
+ } catch (NamingException e) {
+ log.debug("binding of DummyTransactionManager failed", e);
+ }
+ }
+ return instance;
+ }
+
+ public static DummyUserTransaction getUserTransaction() {
+ getInstance();
+ return utx;
+ }
+
+ public static void destroy() {
+ if (instance == null)
+ return;
+ try {
+ Properties p = new Properties();
+ Context ctx = new InitialContext(p);
+ ctx.unbind("java:/TransactionManager");
+ ctx.unbind("UserTransaction");
+ }
+ catch (NamingException e) {
+ log.error("unbinding of DummyTransactionManager failed", e);
+ }
+ instance.setTransaction(null);
+ instance = null;
+ }
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyTransactionManager.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyUserTransaction.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/DummyUserTransaction.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/tm/DummyUserTransaction.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/tm/DummyUserTransaction.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.tm;
+
+
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.UserTransaction;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author bela
+ * <p/>
+ * Date: May 15, 2003 Time: 4:20:17 PM
+ * @since 4.0
+ */
+public class DummyUserTransaction implements UserTransaction, java.io.Serializable {
+ static final Log logger_ = LogFactory.getLog(DummyUserTransaction.class);
+ DummyTransactionManager tm_;
+ private static final long serialVersionUID = -6568400755677046127L;
+
+ /**
+ * List<Synchronization>
+ */
+ List<Synchronization> l = new ArrayList<Synchronization>();
+
+ public DummyUserTransaction(DummyTransactionManager tm) {
+ tm_ = tm;
+ }
+
+
+ /**
+ * Starts a new transaction, and associate it with the calling thread.
+ *
+ * @throws NotSupportedException If the calling thread is already associated with a transaction, and nested
+ * transactions are not supported.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void begin() throws NotSupportedException, SystemException {
+ tm_.begin();
+ }
+
+ /**
+ * Attempt to commit this transaction.
+ *
+ * @throws RollbackException If the transaction was marked for rollback only, the transaction is rolled back
+ * and this exception is thrown.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ * @throws HeuristicMixedException If a heuristic decision was made and some some parts of the transaction have
+ * been committed while other parts have been rolled back.
+ * @throws HeuristicRollbackException If a heuristic decision to roll back the transaction was made.
+ * @throws SecurityException If the caller is not allowed to commit this transaction.
+ */
+ public void commit()
+ throws RollbackException, HeuristicMixedException,
+ HeuristicRollbackException, SecurityException, SystemException {
+
+ tm_.commit();
+ }
+
+ /**
+ * Rolls back this transaction.
+ *
+ * @throws IllegalStateException If the transaction is in a state where it cannot be rolled back. This could be
+ * because the transaction is no longer active, or because it is in the {@link
+ * Status#STATUS_PREPARED prepared state}.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void rollback() throws IllegalStateException, SystemException {
+ tm_.rollback();
+ }
+
+ /**
+ * Mark the transaction so that the only possible outcome is a rollback.
+ *
+ * @throws IllegalStateException If the transaction is not in an active state.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException {
+ tm_.setRollbackOnly();
+ }
+
+ /**
+ * Get the status of the transaction.
+ *
+ * @return The status of the transaction. This is one of the {@link Status} constants.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public int getStatus() throws SystemException {
+ return tm_.getStatus();
+ }
+
+ /**
+ * Change the transaction timeout for transactions started by the calling thread with the {@link #begin()} method.
+ *
+ * @param seconds The new timeout value, in seconds. If this parameter is <code>0</code>, the timeout value is reset
+ * to the default value.
+ * @throws SystemException If the transaction service fails in an unexpected way.
+ */
+ public void setTransactionTimeout(int seconds) throws SystemException {
+ throw new SystemException("not supported");
+ }
+
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyUserTransaction.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyXid.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/tm/DummyXid.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/tm/DummyXid.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,34 @@
+package org.infinispan.transaction.tm;
+
+import javax.transaction.xa.Xid;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author
+ */
+public class DummyXid implements Xid {
+
+ private static AtomicInteger txIdCounter = new AtomicInteger(0);
+ private int id = txIdCounter.incrementAndGet();
+
+ public int getFormatId() {
+ return id;
+ }
+
+ public byte[] getGlobalTransactionId() {
+ throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
+ }
+
+ public byte[] getBranchQualifier() {
+ throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
+ }
+
+ @Override
+ public String toString() {
+ return "DummyXid{" +
+ "id=" + id +
+ '}';
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/tm/DummyXid.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java (from rev 204, trunk/core/src/main/java/org/infinispan/transaction/GlobalTransaction.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.transaction.xa;
+
+import org.infinispan.remoting.transport.Address;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.concurrent.atomic.AtomicLong;
+
+
+/**
+ * Uniquely identifies a transaction that spans all JVMs in a cluster. This is used when replicating all modifications
+ * in a transaction; the PREPARE and COMMIT (or ROLLBACK) messages have to have a unique identifier to associate the
+ * changes with<br>
+ *
+ * @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 12, 2003
+ * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ * @since 4.0
+ */
+public class GlobalTransaction implements Externalizable, Cloneable {
+
+ private static final long serialVersionUID = 8011434781266976149L;
+
+ private static AtomicLong sid = new AtomicLong(0);
+
+ private long id = -1;
+
+ private transient Address addr = null;
+ private transient int hash_code = -1; // in the worst case, hashCode() returns 0, then increases, so we're safe here
+ private transient boolean remote = false;
+
+ /**
+ * empty ctor used by externalization.
+ */
+ public GlobalTransaction() {
+ }
+
+ public GlobalTransaction(Address addr, boolean remote) {
+ this.id = sid.incrementAndGet();
+ this.addr = addr;
+ this.remote = remote;
+ }
+
+ public GlobalTransaction(long id, Address addr) {
+ this.id = id;
+ this.addr = addr;
+ this.remote = true;
+ }
+
+ public GlobalTransaction(boolean remote) {
+ this(null, remote);
+ }
+
+ public Object getAddress() {
+ return addr;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public boolean isRemote() {
+ return remote;
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong(id);
+ out.writeObject(addr);
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ id = in.readLong();
+ addr = (Address) in.readObject();
+ hash_code = -1;
+ }
+
+ @Override
+ public int hashCode() {
+ if (hash_code == -1) {
+ hash_code = (addr != null ? addr.hashCode() : 0) + (int) id;
+ }
+ return hash_code;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other)
+ return true;
+ if (!(other instanceof GlobalTransaction))
+ return false;
+
+ GlobalTransaction otherGtx = (GlobalTransaction) other;
+ boolean aeq = (addr == null) ? (otherGtx.addr == null) : addr.equals(otherGtx.addr);
+ return aeq && (id == otherGtx.id);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("GlobalTransaction:<").append(addr).append(">:").append(id);
+ return sb.toString();
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public void setAddress(Address address) {
+ this.addr = address;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException("Impossible!");
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,214 @@
+package org.infinispan.transaction.xa;
+
+import org.infinispan.commands.CommandsFactory;
+import org.infinispan.commands.tx.CommitCommand;
+import org.infinispan.commands.tx.PrepareCommand;
+import org.infinispan.commands.tx.RollbackCommand;
+import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.config.Configuration;
+import org.infinispan.container.entries.CacheEntry;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.context.impl.InitiatorTxInvocationContext;
+import org.infinispan.interceptors.InterceptorChain;
+import org.infinispan.util.BidirectionalLinkedHashMap;
+import org.infinispan.util.BidirectionalMap;
+import org.infinispan.util.InfinispanCollections;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import javax.transaction.Transaction;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public class TransactionXaAdapter implements XAResource {
+
+ private static Log log = LogFactory.getLog(TransactionXaAdapter.class);
+
+ private int txTimeout;
+
+ private List<WriteCommand> modifications;
+ private BidirectionalMap<Object, CacheEntry> lookedUpEntries;
+
+ private GlobalTransaction transactionIdentifier;
+ private InvocationContextContainer icc;
+ private InterceptorChain invoker;
+
+ private CommandsFactory commandsFactory;
+ private Configuration configuration;
+
+ private TxEnlistingManager txEnlistingManager;
+ private Transaction transaction;
+
+ public TransactionXaAdapter(GlobalTransaction transactionIdentifier, InvocationContextContainer icc, InterceptorChain invoker,
+ CommandsFactory commandsFactory, Configuration configuration, TxEnlistingManager txEnlistingManager,
+ Transaction transaction) {
+ this.transactionIdentifier = transactionIdentifier;
+ this.icc = icc;
+ this.invoker = invoker;
+ this.commandsFactory = commandsFactory;
+ this.configuration = configuration;
+ this.txEnlistingManager = txEnlistingManager;
+ this.transaction = transaction;
+ }
+
+ public void addModification(WriteCommand mod) {
+ if (modifications == null) {
+ modifications = new ArrayList<WriteCommand>(8);
+ }
+ modifications.add(mod);
+ }
+
+ public int prepare(Xid xid) throws XAException {
+ if (configuration.isOnePhaseCommit()) {
+ if (log.isTraceEnabled())
+ log.trace("Recieved prepare for tx: " + xid + " . Skipping call as 1PC will be used.");
+ return XA_OK;
+ }
+
+ PrepareCommand prepareCommand = commandsFactory.buildPrepareCommand(transactionIdentifier, modifications, configuration.isOnePhaseCommit());
+ if (log.isTraceEnabled()) log.trace("Sending prepare command through the chain: " + prepareCommand);
+
+ InitiatorTxInvocationContext ctx = icc.getInitiatorTxInvocationContext();
+ ctx.setXaCache(this);
+ try {
+ invoker.invoke(ctx, prepareCommand);
+ return XA_OK; //todo validate code here
+ } catch (Throwable e) {
+ log.error("Error while processing PrepareCommand", e);
+ throw new XAException(XAException.XAER_RMERR);//todo validate code here
+ }
+ }
+
+ public void commit(Xid xid, boolean b) throws XAException {
+ if (log.isTraceEnabled()) log.trace("commiting TransactionXaAdapter: " + transactionIdentifier);
+ try {
+ InitiatorTxInvocationContext ctx = icc.getInitiatorTxInvocationContext();
+ ctx.setXaCache(this);
+ if (configuration.isOnePhaseCommit()) {
+ if (log.isTraceEnabled()) log.trace("Doing an 1PC prepare call on the interceptor chain");
+ PrepareCommand command = commandsFactory.buildPrepareCommand(transactionIdentifier, modifications, true);
+ try {
+ invoker.invoke(ctx, command);
+ } catch (Throwable e) {
+ log.error("Error while processing 1PC PrepareCommand", e);
+ throw new XAException(XAException.XAER_RMERR);
+ }
+ } else {
+ CommitCommand commitCommand = commandsFactory.buildCommitCommand(transactionIdentifier);
+ try {
+ invoker.invoke(ctx, commitCommand);
+ } catch (Throwable e) {
+ log.error("Error while processing 1PC PrepareCommand", e);
+ throw new XAException(XAException.XAER_RMERR);
+ }
+ }
+ } finally {
+ txEnlistingManager.delist(transaction);
+ this.modifications = null;
+ }
+ }
+
+ public void rollback(Xid xid) throws XAException {
+ RollbackCommand rollbackCommand = commandsFactory.buildRollbackCommand(transactionIdentifier);
+ InitiatorTxInvocationContext ctx = icc.getInitiatorTxInvocationContext();
+ ctx.setXaCache(this);
+ try {
+ invoker.invoke(ctx, rollbackCommand);
+ } catch (Throwable e) {
+ log.error("Exception while ", e);
+ throw new XAException(XAException.XA_HEURHAZ);
+ } finally {
+ txEnlistingManager.delist(transaction);
+ this.modifications = null;
+ }
+ }
+
+ public void start(Xid xid, int i) throws XAException {
+ if (log.isTraceEnabled()) log.trace("start called");
+ }
+
+ public void end(Xid xid, int i) throws XAException {
+ if (log.isTraceEnabled()) log.trace("end called");
+ }
+
+ public void forget(Xid xid) throws XAException {
+ if (log.isTraceEnabled()) log.trace("forget called");
+ }
+
+ public int getTransactionTimeout() throws XAException {
+ if (log.isTraceEnabled()) log.trace("start called");
+ return txTimeout;
+ }
+
+ public boolean isSameRM(XAResource xaResource) throws XAException {
+ if (!(xaResource instanceof TransactionXaAdapter)) {
+ return false;
+ }
+ TransactionXaAdapter other = (TransactionXaAdapter) xaResource;
+ return other.transactionIdentifier.equals(this.transactionIdentifier);
+ }
+
+ public Xid[] recover(int i) throws XAException {
+ if (log.isTraceEnabled()) log.trace("recover called: " + i);
+ return null; //todo validate with javadoc
+ }
+
+ public boolean setTransactionTimeout(int i) throws XAException {
+ this.txTimeout = i;
+ return true; //todo check javadoc
+ }
+
+ public void putLookedUpEntries(Map<Object, CacheEntry> entries) {
+ initLookedUpEntries();
+ lookedUpEntries.putAll(entries);
+ }
+
+ public CacheEntry lookupEntry(Object key) {
+ if (lookedUpEntries == null) return null;
+ return lookedUpEntries.get(key);
+ }
+
+ public BidirectionalMap<Object, CacheEntry> getLookedUpEntries() {
+ return (BidirectionalMap<Object, CacheEntry>)
+ (lookedUpEntries == null ? InfinispanCollections.emptyBidirectionalMap() : lookedUpEntries);
+ }
+
+ public void putLookedUpEntry(Object key, CacheEntry e) {
+ initLookedUpEntries();
+ lookedUpEntries.put(key, e);
+ }
+
+ public void removeLookedUpEntry(Object key) {
+ if (lookedUpEntries != null) lookedUpEntries.remove(key);
+ }
+
+ public void clearLookedUpEntries() {
+ if (lookedUpEntries != null) lookedUpEntries.clear();
+ }
+
+ private void initLookedUpEntries() {
+ if (lookedUpEntries == null) lookedUpEntries = new BidirectionalLinkedHashMap<Object, CacheEntry>(4);
+ }
+
+ public GlobalTransaction getTransactionIdentifier() {
+ return transactionIdentifier;
+ }
+
+ public List<WriteCommand> getModifications() {
+ return modifications;
+ }
+
+ public Transaction getTransaction() {
+ return transaction;
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/core/src/main/java/org/infinispan/transaction/xa/TxEnlistingManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/TxEnlistingManager.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/TxEnlistingManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -0,0 +1,154 @@
+package org.infinispan.transaction.xa;
+
+import org.infinispan.CacheException;
+import org.infinispan.commands.CommandsFactory;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.context.impl.RemoteTxInvocationContext;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.interceptors.InterceptorChain;
+import org.infinispan.notifications.cachelistener.CacheNotifier;
+import org.infinispan.remoting.rpc.CacheRpcManager;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * // TODO: Mircea: Document this!
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.0
+ */
+public class TxEnlistingManager {
+ private TransactionManager tm;
+ private InvocationContextContainer icc;
+ private InterceptorChain invoker;
+ private CacheNotifier notifier;
+
+ private Map<Transaction, TransactionXaAdapter> tx2XaCacheMapping = new ConcurrentHashMap<Transaction, TransactionXaAdapter>();
+ private Map<GlobalTransaction, RemoteTxInvocationContext> remoteTxMap;
+ private CommandsFactory commandsFactory;
+ private CacheRpcManager rpcManager;
+ private Configuration configuration;
+
+ @Inject
+ public void initialize(CommandsFactory commandsFactory, CacheRpcManager rpcManager, Configuration configuration,
+ InvocationContextContainer icc, InterceptorChain invoker,
+ TransactionManager tm, CacheNotifier notifier) {
+ this.commandsFactory = commandsFactory;
+ this.rpcManager = rpcManager;
+ this.configuration = configuration;
+ this.tm = tm;
+ this.icc = icc;
+ this.invoker = invoker;
+ this.notifier = notifier;
+ }
+
+ public TransactionXaAdapter enlist(InvocationContext ctx) throws SystemException, RollbackException {
+ Transaction transaction = tm.getTransaction();
+ if (transaction == null) throw new IllegalStateException("This should only be called in an tx scope");
+ if (!isValid(transaction)) throw new IllegalStateException("Transaction " + transaction +
+ " is not in a valid state to be invoking cache operations on.");
+ TransactionXaAdapter current = tx2XaCacheMapping.get(transaction);
+ if (current == null) {
+ GlobalTransaction tx = rpcManager == null ? new GlobalTransaction(false) : new GlobalTransaction(rpcManager.getLocalAddress(), false);
+ current = new TransactionXaAdapter(tx, icc, invoker, commandsFactory, configuration, this, transaction);
+ tx2XaCacheMapping.put(transaction, current);
+ transaction.enlistResource(current);
+ notifier.notifyTransactionRegistered(tx, ctx);
+ }
+ return current;
+ }
+
+ public void delist(Transaction transaction) {
+ if (transaction == null) throw new IllegalArgumentException("Null not allowed");
+ TransactionXaAdapter xaAdapter = tx2XaCacheMapping.remove(transaction);
+ if (xaAdapter == null) {
+ throw new IllegalStateException("This method should only be called by a thread that has a tx association.");
+ }
+ }
+
+ public boolean inTxScope() {
+ try {
+ if (tm == null) return false;
+ Transaction transaction = tm.getTransaction();
+ return transaction != null;
+ } catch (SystemException e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public Transaction getOngoingTx() {
+ try {
+ return tm.getTransaction();
+ } catch (SystemException e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public int getNumberOfInitiatedTx() {
+ return tx2XaCacheMapping.size();
+ }
+
+ private boolean isValid(Transaction tx) {
+ return isActive(tx) || isPreparing(tx);
+ }
+
+ /**
+ * Returns true if transaction is PREPARING, false otherwise
+ */
+ private boolean isPreparing(Transaction tx) {
+ if (tx == null) return false;
+ int status;
+ try {
+ status = tx.getStatus();
+ return status == Status.STATUS_PREPARING;
+ }
+ catch (SystemException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if transaction is ACTIVE, false otherwise
+ */
+ private boolean isActive(Transaction tx) {
+ if (tx == null) return false;
+ int status;
+ try {
+ status = tx.getStatus();
+ return status == Status.STATUS_ACTIVE;
+ }
+ catch (SystemException e) {
+ return false;
+ }
+ }
+
+ public int getActiveLocallyInitiatedTxCount() {
+ if (this.tx2XaCacheMapping == null) return 0;
+ return tx2XaCacheMapping.size();
+ }
+
+ public int getActiveRemotelyInitiatedTxCount() {
+ if (this.remoteTxMap == null) return 0;
+ return this.remoteTxMap.size();
+ }
+
+ public TransactionXaAdapter getXaCache(Transaction tx) {
+ return tx2XaCacheMapping.get(tx);
+ }
+
+ public Transaction getRunningTx() {
+ try {
+ return tm == null ? null : tm.getTransaction();
+ } catch (SystemException e) {
+ throw new CacheException(e);
+ }
+ }
+}
Property changes on: trunk/core/src/main/java/org/infinispan/transaction/xa/TxEnlistingManager.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManager.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManager.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -31,24 +31,12 @@
* @since 4.0
*/
public interface LockManager {
- /**
- * Determines the owner to be used when obtaining locks, given an invocation context. This is typically a {@link
- * org.infinispan.transaction.GlobalTransaction} if one is present in the context, or {@link Thread#currentThread()}
- * if one is not present.
- *
- * @param ctx invocation context
- * @return owner to be used for acquiring locks.
- */
- Object getLockOwner(InvocationContext ctx);
/**
* Acquires a lock of type lockType, on a specific entry in the cache. This method will try for a period of time and
* give up if it is unable to acquire the required lock. The period of time is specified in {@link
* org.infinispan.config.Configuration#getLockAcquisitionTimeout()}.
* <p/>
- * The owner for the lock is determined by passing the invocation context to {@link
- * #getLockOwner(InvocationContext)}.
- * <p/>
*
* @param key key to lock
* @param ctx invocation context associated with this invocation
@@ -69,8 +57,6 @@
* <p/>
* Locks are released in reverse order of which they are acquired and registered.
* <p/>
- * Lock owner is determined by passing the invocation context to {@link #getLockOwner(InvocationContext)}
- * <p/>
*
* @param ctx invocation context to inspect
*/
Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManagerImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/LockManagerImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -25,7 +25,7 @@
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.jmx.annotations.MBean;
@@ -74,15 +74,10 @@
transactionManager == null ? new ReentrantPerEntryLockContainer(configuration.getConcurrencyLevel()) : new OwnableReentrantPerEntryLockContainer(configuration.getConcurrencyLevel(), invocationContextContainer);
}
- public Object getLockOwner(InvocationContext ctx) {
- return ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread();
- }
-
public boolean lockAndRecord(Object key, InvocationContext ctx) throws InterruptedException {
long lockTimeout = getLockAcquisitionTimeout(ctx);
if (trace) log.trace("Attempting to lock {0} with acquisition timeout of {1} millis", key, lockTimeout);
if (lockContainer.acquireLock(key, lockTimeout, MILLISECONDS)) {
- ctx.setContainsLocks(true);
return true;
}
Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/OwnableReentrantLock.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/OwnableReentrantLock.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/OwnableReentrantLock.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -22,8 +22,10 @@
package org.infinispan.util.concurrent.locks;
import net.jcip.annotations.ThreadSafe;
-import org.infinispan.context.InvocationContextContainer;
-import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
@@ -31,8 +33,8 @@
/**
* A lock that supports reentrancy based on owner (and not on current thread). For this to work, the lock needs to be
- * constructed with a reference to the {@link org.infinispan.context.InvocationContextContainer}, so it is able to
- * determine whether the caller's "owner" reference is the current thread or a {@link GlobalTransaction} instance.
+ * constructed with a reference to the {@link org.infinispan.context.container.InvocationContextContainer}, so it is able to determine whether the
+ * caller's "owner" reference is the current thread or a {@link org.infinispan.transaction.xa.GlobalTransaction} instance.
* <p/>
* This makes this lock implementation very closely tied to Infinispan internals, but it provides for a very clean,
* efficient and moreover familiar interface to work with, since it implements {@link java.util.concurrent.locks.Lock}.
@@ -45,6 +47,8 @@
*/
@ThreadSafe
public class OwnableReentrantLock extends AbstractQueuedSynchronizer implements Lock {
+
+ private static Log log = LogFactory.getLog(OwnableReentrantLock.class);
/**
* Current owner
*/
@@ -52,18 +56,18 @@
/**
* Invocation context to consult when testing the current requestor
*/
- transient InvocationContextContainer invocationContextContainer;
+ transient InvocationContextContainer icc;
/**
* Creates a new lock instance.
*
- * @param invocationContextContainer InvocationContextContainer instance to consult for the invocation context of the
+ * @param icc InvocationContextContainer instance to consult for the invocation context of the
* call.
*/
- public OwnableReentrantLock(InvocationContextContainer invocationContextContainer) {
- if (invocationContextContainer == null)
+ public OwnableReentrantLock(InvocationContextContainer icc) {
+ if (icc == null)
throw new IllegalArgumentException("Invocation context container cannot be null!");
- this.invocationContextContainer = invocationContextContainer;
+ this.icc = icc;
}
/**
@@ -71,8 +75,9 @@
* otherwise.
*/
protected final Object currentRequestor() {
- GlobalTransaction gtx;
- return (gtx = invocationContextContainer.get().getGlobalTransaction()) == null ? Thread.currentThread() : gtx;
+ InvocationContext invocationContext = icc.getThreadContext();
+ Object o = invocationContext.getLockOwner();
+ return o;
}
public void lock() {
Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantPerEntryLockContainer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,6 +1,6 @@
package org.infinispan.util.concurrent.locks.containers;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.util.concurrent.locks.OwnableReentrantLock;
import java.util.concurrent.locks.Lock;
Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/OwnableReentrantStripedLockContainer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -22,7 +22,7 @@
package org.infinispan.util.concurrent.locks.containers;
import net.jcip.annotations.ThreadSafe;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.util.concurrent.locks.OwnableReentrantLock;
import java.util.Arrays;
Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/ReentrantStripedLockContainer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/ReentrantStripedLockContainer.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/containers/ReentrantStripedLockContainer.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -59,7 +59,10 @@
public final int getNumLocksHeld() {
int i = 0;
- for (ReentrantLock l : sharedLocks) if (l.isLocked()) i++;
+ for (ReentrantLock l : sharedLocks)
+ if (l.isLocked()) {
+ i++;
+ }
return i;
}
Modified: trunk/core/src/main/resources/config-samples/all.xml
===================================================================
--- trunk/core/src/main/resources/config-samples/all.xml 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/main/resources/config-samples/all.xml 2009-05-12 02:58:05 UTC (rev 252)
@@ -71,7 +71,7 @@
Used to register a transaction manager and participate in ongoing transactions.
-->
<transaction
- transactionManagerLookupClass="org.infinispan.transaction.GenericTransactionManagerLookup"
+ transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
syncRollbackPhase="false"
syncCommitPhase="false"/>
Modified: trunk/core/src/test/java/org/infinispan/api/CacheAPITest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/CacheAPITest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/CacheAPITest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -6,8 +6,8 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManager;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.transaction.tm.DummyTransactionManager;
import org.infinispan.util.concurrent.IsolationLevel;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
@@ -23,7 +23,7 @@
*/
@Test(groups = "functional")
public abstract class CacheAPITest extends SingleCacheManagerTest {
- Cache cache;
+ protected Cache cache;
protected CacheManager createCacheManager() throws Exception {
// start a single cache instance
Modified: trunk/core/src/test/java/org/infinispan/api/batch/BatchWithTMTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/batch/BatchWithTMTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/batch/BatchWithTMTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -5,7 +5,7 @@
import org.infinispan.config.Configuration;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
Modified: trunk/core/src/test/java/org/infinispan/api/mvcc/LockAssert.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/mvcc/LockAssert.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/mvcc/LockAssert.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,7 +1,9 @@
package org.infinispan.api.mvcc;
import org.infinispan.Cache;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.test.TestingUtil;
import org.infinispan.util.concurrent.locks.LockManager;
import org.infinispan.util.concurrent.locks.containers.LockContainer;
@@ -19,13 +21,18 @@
public static void assertNotLocked(Object key, InvocationContextContainer icc) {
// can't rely on the negative test since other entries may share the same lock with lock striping.
- assert !icc.get().hasLockedKey(key) : key + " lock recorded!";
+ assert !icc.getLocalInvocationContext(true).hasLockedKey(key) : key + " lock recorded!";
}
public static void assertNoLocks(LockManager lockManager, InvocationContextContainer icc) {
LockContainer lc = (LockContainer) TestingUtil.extractField(lockManager, "lockContainer");
assert lc.getNumLocksHeld() == 0 : "Stale locks exist! NumLocksHeld is " + lc.getNumLocksHeld() + " and lock info is " + lockManager.printLockInfo();
- assert !icc.get().isContainsModifications() : "Stale (?) locks recorded!";
+ InvocationContext invocationContext = icc.getThreadContext();
+ if (invocationContext instanceof TxInvocationContext) {
+ TxInvocationContext txContext = (TxInvocationContext) invocationContext;
+ int modCount = txContext.getModifications() == null ? 0 : txContext.getModifications().size();
+ assert modCount == 0 : " expected 0 modifications but were " + modCount ;
+ }
}
public static void assertNoLocks(Cache cache) {
Modified: trunk/core/src/test/java/org/infinispan/api/mvcc/LockPerEntryTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/mvcc/LockPerEntryTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/mvcc/LockPerEntryTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -2,7 +2,7 @@
import org.infinispan.Cache;
import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.TestingUtil;
Modified: trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -2,11 +2,11 @@
import org.infinispan.Cache;
import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.infinispan.util.concurrent.TimeoutException;
import org.infinispan.util.concurrent.locks.LockManager;
Modified: trunk/core/src/test/java/org/infinispan/api/mvcc/PutForExternalReadTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/mvcc/PutForExternalReadTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/mvcc/PutForExternalReadTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -8,17 +8,17 @@
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.config.Configuration;
import org.infinispan.context.Flag;
-import org.infinispan.remoting.ResponseFilter;
-import org.infinispan.remoting.ResponseMode;
-import org.infinispan.remoting.RpcManager;
-import org.infinispan.remoting.RpcManagerImpl;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.remoting.rpc.RpcManagerImpl;
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.Transport;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.ReplListener;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
-import org.infinispan.transaction.TransactionTable;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.transaction.xa.TxEnlistingManager;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
@@ -226,8 +226,8 @@
cacheModeLocalTest(true);
}
- private TransactionTable getTransactionTable(Cache cache) {
- return TestingUtil.extractComponent(cache, TransactionTable.class);
+ private TxEnlistingManager getTxEnlistingManager(Cache cache) {
+ return TestingUtil.extractComponent(cache, TxEnlistingManager.class);
}
/**
@@ -240,13 +240,13 @@
tm1.commit();
replListener2.waitForRpc();
- TransactionTable tt1 = getTransactionTable(cache1);
- TransactionTable tt2 = getTransactionTable(cache2);
+ TxEnlistingManager tt1 = getTxEnlistingManager(cache1);
+ TxEnlistingManager tt2 = getTxEnlistingManager(cache2);
- assert tt1.getNumGlobalTransactions() == 0 : "Cache 1 should have no stale global TXs";
- assert tt1.getNumLocalTransactions() == 0 : "Cache 1 should have no stale local TXs";
- assert tt2.getNumGlobalTransactions() == 0 : "Cache 2 should have no stale global TXs";
- assert tt2.getNumLocalTransactions() == 0 : "Cache 2 should have no stale local TXs";
+ assert tt1.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 1 should have no stale global TXs";
+ assert tt1.getActiveLocallyInitiatedTxCount() == 0 : "Cache 1 should have no stale local TXs";
+ assert tt2.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 2 should have no stale global TXs";
+ assert tt2.getActiveLocallyInitiatedTxCount() == 0 : "Cache 2 should have no stale local TXs";
System.out.println("PutForExternalReadTest.testMemLeakOnSuspendedTransactions");
replListener2.expectWithTx(PutKeyValueCommand.class);
@@ -256,10 +256,10 @@
tm1.commit();
replListener2.waitForRpc();
- assert tt1.getNumGlobalTransactions() == 0 : "Cache 1 should have no stale global TXs";
- assert tt1.getNumLocalTransactions() == 0 : "Cache 1 should have no stale local TXs";
- assert tt2.getNumGlobalTransactions() == 0 : "Cache 2 should have no stale global TXs";
- assert tt2.getNumLocalTransactions() == 0 : "Cache 2 should have no stale local TXs";
+ assert tt1.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 1 should have no stale global TXs";
+ assert tt1.getActiveLocallyInitiatedTxCount() == 0 : "Cache 1 should have no stale local TXs";
+ assert tt2.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 2 should have no stale global TXs";
+ assert tt2.getActiveLocallyInitiatedTxCount() == 0 : "Cache 2 should have no stale local TXs";
replListener2.expectWithTx(PutKeyValueCommand.class);
tm1.begin();
@@ -268,10 +268,10 @@
tm1.commit();
replListener2.waitForRpc();
- assert tt1.getNumGlobalTransactions() == 0 : "Cache 1 should have no stale global TXs";
- assert tt1.getNumLocalTransactions() == 0 : "Cache 1 should have no stale local TXs";
- assert tt2.getNumGlobalTransactions() == 0 : "Cache 2 should have no stale global TXs";
- assert tt2.getNumLocalTransactions() == 0 : "Cache 2 should have no stale local TXs";
+ assert tt1.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 1 should have no stale global TXs";
+ assert tt1.getActiveLocallyInitiatedTxCount() == 0 : "Cache 1 should have no stale local TXs";
+ assert tt2.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 2 should have no stale global TXs";
+ assert tt2.getActiveLocallyInitiatedTxCount() == 0 : "Cache 2 should have no stale local TXs";
replListener2.expectWithTx(PutKeyValueCommand.class, PutKeyValueCommand.class);
tm1.begin();
@@ -281,10 +281,10 @@
tm1.commit();
replListener2.waitForRpc();
- assert tt1.getNumGlobalTransactions() == 0 : "Cache 1 should have no stale global TXs";
- assert tt1.getNumLocalTransactions() == 0 : "Cache 1 should have no stale local TXs";
- assert tt2.getNumGlobalTransactions() == 0 : "Cache 2 should have no stale global TXs";
- assert tt2.getNumLocalTransactions() == 0 : "Cache 2 should have no stale local TXs";
+ assert tt1.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 1 should have no stale global TXs";
+ assert tt1.getActiveLocallyInitiatedTxCount() == 0 : "Cache 1 should have no stale local TXs";
+ assert tt2.getActiveRemotelyInitiatedTxCount() == 0 : "Cache 2 should have no stale global TXs";
+ assert tt2.getActiveLocallyInitiatedTxCount() == 0 : "Cache 2 should have no stale local TXs";
}
/**
Modified: trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/RepeatableReadLockTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/RepeatableReadLockTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/RepeatableReadLockTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -112,4 +112,31 @@
tx.commit();
assert cache.get("a") == null;
}
+
+ public void testLocksOnPutKeyVal() throws Exception {
+ LockTestBaseTL tl = threadLocal.get();
+ Cache<String, String> cache = tl.cache;
+ TransactionManager tm = tl.tm;
+ tm.begin();
+ cache.put("k", "v");
+ assertLocked("k");
+ tm.commit();
+
+ assertNoLocks();
+
+ tm.begin();
+ assert cache.get("k").equals("v");
+ assertNotLocked("k");
+ tm.commit();
+
+ assertNoLocks();
+
+ tm.begin();
+ cache.remove("k");
+ assertLocked("k");
+ tm.commit();
+
+ assertNoLocks();
+ }
+
}
Modified: trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/WriteSkewTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/WriteSkewTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/api/mvcc/repeatable_read/WriteSkewTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -3,11 +3,11 @@
import org.infinispan.Cache;
import org.infinispan.api.mvcc.LockAssert;
import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.infinispan.util.concurrent.locks.LockManager;
import org.testng.annotations.AfterTest;
Modified: trunk/core/src/test/java/org/infinispan/atomic/APITest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/APITest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/atomic/APITest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -26,7 +26,7 @@
import static org.infinispan.atomic.AtomicHashMapTestAssertions.assertIsEmptyMap;
import org.infinispan.config.Configuration;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
@@ -121,11 +121,10 @@
tm.begin();
map.put("blah", "blah");
- assert map.size() == 1;
assert map.get("blah").equals("blah");
- assert map.containsKey("blah");
- Transaction t = tm.suspend();
+ Transaction t = tm.suspend();
+ assert map.size() == 0;
assertIsEmpty(map);
assertIsEmptyMap(cache, "map");
Modified: trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapConcurrencyTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -5,7 +5,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.concurrent.TimeoutException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
Modified: trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/atomic/AtomicHashMapTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -25,6 +25,8 @@
import org.easymock.EasyMock;
import org.testng.annotations.Test;
+import org.infinispan.atomic.atomichashmap.AtomicHashMap;
+import org.infinispan.atomic.atomichashmap.AtomicHashMapDelta;
import java.io.IOException;
import java.io.ObjectOutput;
Modified: trunk/core/src/test/java/org/infinispan/atomic/AtomicMapFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/AtomicMapFunctionalTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/atomic/AtomicMapFunctionalTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -4,11 +4,11 @@
import org.infinispan.config.Configuration;
import static org.infinispan.context.Flag.SKIP_LOCKING;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import org.testng.annotations.AfterMethod;
@@ -73,10 +73,10 @@
AtomicMap<String, String> map = cache.getAtomicMap("key");
assert map.isEmpty();
InvocationContextContainer icc = TestingUtil.extractComponent(cache, InvocationContextContainer.class);
- InvocationContext ic = icc.get();
+ InvocationContext ic = icc.getLocalInvocationContext(true);
ic.setFlags(SKIP_LOCKING);
log.debug("Doing a put");
- assert icc.get().hasFlag(SKIP_LOCKING);
+ assert icc.getLocalInvocationContext(false).hasFlag(SKIP_LOCKING);
map.put("a", "b");
log.debug("Put complete");
assert map.get("a").equals("b");
@@ -89,7 +89,7 @@
AtomicMap<String, String> map = cache.getAtomicMap("key");
tm.begin();
assert map.isEmpty();
- TestingUtil.extractComponent(cache, InvocationContextContainer.class).get().setFlags(SKIP_LOCKING);
+ TestingUtil.extractComponent(cache, InvocationContextContainer.class).getLocalInvocationContext(true).setFlags(SKIP_LOCKING);
map.put("a", "b");
assert map.get("a").equals("b");
Transaction t = tm.suspend();
@@ -108,7 +108,7 @@
assert map.isEmpty();
map.put("x", "y");
assert map.get("x").equals("y");
- TestingUtil.extractComponent(cache, InvocationContextContainer.class).get().setFlags(SKIP_LOCKING);
+ TestingUtil.extractComponent(cache, InvocationContextContainer.class).getLocalInvocationContext(true).setFlags(SKIP_LOCKING);
log.debug("Doing a put");
map.put("a", "b");
log.debug("Put complete");
Modified: trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/atomic/ClusteredAPITest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -5,8 +5,8 @@
import static org.infinispan.atomic.AtomicHashMapTestAssertions.assertIsEmptyMap;
import org.infinispan.config.Configuration;
import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.transaction.DummyTransactionManager;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.tm.DummyTransactionManager;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.Test;
import java.util.List;
Modified: trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -9,7 +9,7 @@
import org.infinispan.loaders.decorators.SingletonStoreConfig;
import org.infinispan.loaders.file.FileCacheStore;
import org.infinispan.loaders.file.FileCacheStoreConfig;
-import org.infinispan.transaction.GenericTransactionManagerLookup;
+import org.infinispan.transaction.lookup.GenericTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.testng.annotations.Test;
import org.w3c.dom.Element;
Modified: trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -51,7 +51,7 @@
Configuration c = namedCaches.get("transactional");
- assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.GenericTransactionManagerLookup");
+ assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.lookup.GenericTransactionManagerLookup");
c = namedCaches.get("syncRepl");
@@ -75,7 +75,7 @@
c = namedCaches.get("txSyncRepl");
- assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.GenericTransactionManagerLookup");
+ assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.lookup.GenericTransactionManagerLookup");
assert c.getCacheMode() == Configuration.CacheMode.REPL_SYNC;
assert !c.isFetchInMemoryState();
assert c.getSyncReplTimeout() == 15000;
@@ -127,7 +127,7 @@
c.applyOverrides(namedCaches.get("transactional"));
assert c.getCacheMode() == Configuration.CacheMode.LOCAL;
- assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.GenericTransactionManagerLookup");
+ assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.lookup.GenericTransactionManagerLookup");
assert c.getLockAcquisitionTimeout() == 1000;
assert c.getConcurrencyLevel() == 100;
assert c.getIsolationLevel() == IsolationLevel.READ_COMMITTED;
@@ -171,7 +171,7 @@
c = defaultCfg.clone();
c.applyOverrides(namedCaches.get("txSyncRepl"));
- assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.GenericTransactionManagerLookup");
+ assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.lookup.GenericTransactionManagerLookup");
assert c.getCacheMode() == Configuration.CacheMode.REPL_SYNC;
assert !c.isFetchInMemoryState();
assert c.getSyncReplTimeout() == 15000;
Modified: trunk/core/src/test/java/org/infinispan/distribution/BaseDistFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/distribution/BaseDistFunctionalTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/distribution/BaseDistFunctionalTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -13,7 +13,7 @@
import org.infinispan.remoting.transport.Address;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.testng.annotations.Test;
Modified: trunk/core/src/test/java/org/infinispan/distribution/DistSyncFuncTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/distribution/DistSyncFuncTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/distribution/DistSyncFuncTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -90,10 +90,15 @@
assertOnAllCachesAndOwnership("k1", "value");
- retval = getFirstNonOwner("k1").remove("k1", "value");
+ assert caches.get(1).get("k1").equals("value");
+
+ Cache<Object, String> owner = getFirstNonOwner("k1");
+
+ retval = owner.remove("k1", "value");
asyncWait("k1", RemoveCommand.class, getSecondNonOwner("k1"));
if (testRetVals) assert retval : "Should have removed entry";
+ assert caches.get(1).get("k1") == null: "expected null but received " + caches.get(1).get("k1");
assertOnAllCachesAndOwnership("k1", null);
}
Modified: trunk/core/src/test/java/org/infinispan/distribution/DistSyncTxFuncTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/distribution/DistSyncTxFuncTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/distribution/DistSyncTxFuncTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,6 +1,9 @@
package org.infinispan.distribution;
+import org.infinispan.Cache;
import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.locks.LockManager;
import org.testng.annotations.Test;
import javax.transaction.TransactionManager;
@@ -18,7 +21,7 @@
// no op. Meant to be overridden
}
- private void init(MagicKey k1, MagicKey k2) {
+ protected void init(MagicKey k1, MagicKey k2) {
// neither key maps on to c4
c2.put(k1, "value1");
asyncWait(k1, PutKeyValueCommand.class);
@@ -46,13 +49,17 @@
// now test a transaction that spans both keys.
TransactionManager tm4 = getTransactionManager(c4);
+ asserLocked(c3, false, k1);
tm4.begin();
c4.put(k1, "new_value1");
c4.put(k2, "new_value2");
tm4.commit();
- asyncTxWait(k1, k2);
+ asyncTxWait("new_value1","new_value2");
+ asserLocked(c3, false, k1);
+ asserLocked(c3, false, k2);
+
assertIsInContainerImmortal(c1, k1);
assertIsInContainerImmortal(c2, k1);
assertIsInContainerImmortal(c2, k2);
@@ -63,10 +70,23 @@
assertIsNotInL1(c1, k2);
assertIsNotInL1(c3, k1);
+ asserLocked(c4, false, k1, k2);
+ asserLocked(c3, false, k1);
+ asserLocked(c3, false, k2);
+ asserLocked(c1, false, k1, k2);
+ asserLocked(c2, false, k1, k2);
checkOwnership(k1, k2, "new_value1", "new_value2");
}
- private void checkOwnership(MagicKey k1, MagicKey k2, String v1, String v2) {
+ void asserLocked(Cache c, boolean isLocked, Object... keys) {
+ LockManager lm = TestingUtil.extractComponent(c, LockManager.class);
+ for (Object key : keys) {
+ assert isLocked == lm.isLocked(key) : " expecting key '" + key + "' to be " + (isLocked ? " locked " :
+ "not locked + \n Lock owner is:" + lm.getOwner(key));
+ }
+ }
+
+ protected void checkOwnership(MagicKey k1, MagicKey k2, String v1, String v2) {
assertOnAllCachesAndOwnership(k1, v1);
assertOnAllCachesAndOwnership(k2, v2);
@@ -139,6 +159,8 @@
init(k1, k2);
TransactionManager tm4 = getTransactionManager(c4);
+ LockManager lockManager4 = TestingUtil.extractComponent(c4, LockManager.class);
+
tm4.begin();
Object ret = c4.putIfAbsent(k1, "new_value");
if (testRetVals) assert "value1".equals(ret) : "Was expecting value1 but was " + ret;
@@ -148,8 +170,14 @@
assert c4.get(k1).equals("value1");
assert c4.get(k2).equals("value2");
+ assert lockManager4.isLocked(k1);
+ assert lockManager4.isLocked(k2);
+
tm4.rollback();
+ assert !lockManager4.isLocked(k1);
+ assert !lockManager4.isLocked(k2);
+
assert c2.get(k1).equals("value1");
assert c2.get(k2).equals("value2");
Modified: trunk/core/src/test/java/org/infinispan/invalidation/BaseInvalidationTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/invalidation/BaseInvalidationTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/invalidation/BaseInvalidationTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -9,15 +9,16 @@
import org.infinispan.commands.write.InvalidateCommand;
import org.infinispan.config.Configuration;
import org.infinispan.context.Flag;
-import org.infinispan.remoting.ResponseFilter;
-import org.infinispan.remoting.ResponseMode;
-import org.infinispan.remoting.RpcManager;
-import org.infinispan.remoting.RpcManagerImpl;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.remoting.rpc.RpcManagerImpl;
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.Transport;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.util.concurrent.locks.LockManager;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
@@ -132,8 +133,6 @@
TransactionManager mgr1 = TestingUtil.getTransactionManager(cache1);
TransactionManager mgr2 = TestingUtil.getTransactionManager(cache2);
- replListener(cache1).expect(InvalidateCommand.class);
- replListener(cache2).expect(InvalidateCommand.class);
mgr1.begin();
cache1.put("key", "value2");
Transaction tx1 = mgr1.suspend();
@@ -143,12 +142,13 @@
mgr1.resume(tx1);
// this oughtta fail
try {
+ replListener(cache2).expect(InvalidateCommand.class);
mgr1.commit();
if (isSync) {
fail("Ought to have failed!");
} else {
assert true : "Ought to have succeeded";
-// replListener(cache2).waitForRpc();
+ replListener(cache2).waitForRpc();
}
}
catch (RollbackException roll) {
@@ -160,15 +160,20 @@
mgr2.resume(tx2);
try {
+ replListener(cache1).expect(InvalidateCommand.class);
mgr2.commit();
- replListener(cache1).waitForRpc();
- if (!isSync) replListener(cache2).waitForRpc();
+ if (!isSync) replListener(cache1).waitForRpc();
assertTrue("Ought to have succeeded!", true);
}
catch (RollbackException roll) {
fail("Ought to have succeeded!");
}
+ LockManager lm1 = TestingUtil.extractComponent(cache1, LockManager.class);
+ LockManager lm2 = TestingUtil.extractComponent(cache2, LockManager.class);
+ assert !lm1.isLocked("key");
+ assert !lm2.isLocked("key");
+
LockAssert.assertNoLocks(cache1);
LockAssert.assertNoLocks(cache2);
}
Modified: trunk/core/src/test/java/org/infinispan/jmx/MvccLockManagerMBeanTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/jmx/MvccLockManagerMBeanTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/jmx/MvccLockManagerMBeanTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -6,7 +6,7 @@
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.Test;
import javax.management.MBeanServer;
Modified: trunk/core/src/test/java/org/infinispan/jmx/RpcManagerMBeanTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/jmx/RpcManagerMBeanTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/jmx/RpcManagerMBeanTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -7,13 +7,14 @@
import org.infinispan.config.Configuration;
import org.infinispan.config.GlobalConfiguration;
import org.infinispan.manager.CacheManager;
-import org.infinispan.remoting.RpcManager;
-import org.infinispan.remoting.RpcManagerImpl;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.remoting.rpc.RpcManagerImpl;
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.Transport;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
+import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import javax.management.MBeanServer;
@@ -88,14 +89,13 @@
mBeanServer.getAttribute(rpcManager1, "ReplicationCount").equals("N/A");
- //now reset statistics
+ //now resume statistics
mBeanServer.invoke(rpcManager1, "resetStatistics", new Object[0], new String[0]);
assert mBeanServer.getAttribute(rpcManager1, "ReplicationCount").equals("0");
assert mBeanServer.getAttribute(rpcManager1, "ReplicationFailures").equals("0");
}
-
@Test(dependsOnMethods = "testEnableJmxStats")
public void testSuccessRatio() throws Exception {
assert mBeanServer.getAttribute(rpcManager1, "ReplicationCount").equals("0");
@@ -115,11 +115,11 @@
EasyMock.expect(transport.getMembers()).andReturn(new LinkedList<Address>()).anyTimes();
replay(transport);
rpcManager.setTransport(transport);
- cache1.put("a6", "b6");
+ cache1.put("a5", "b5");
assert false : "rpc manager should had thrown an expception";
} catch (Throwable e) {
//expected
- assert mBeanServer.getAttribute(rpcManager1, "SuccessRatio").equals("80%");
+ assertEquals(mBeanServer.getAttribute(rpcManager1, "SuccessRatio"), ("80%"));
}
finally {
rpcManager.setTransport(originalTransport);
Modified: trunk/core/src/test/java/org/infinispan/jmx/TxInterceptorMBeanTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/jmx/TxInterceptorMBeanTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/jmx/TxInterceptorMBeanTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -7,7 +7,7 @@
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
Modified: trunk/core/src/test/java/org/infinispan/loaders/CacheLoaderFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/CacheLoaderFunctionalTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/loaders/CacheLoaderFunctionalTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -12,7 +12,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
Modified: trunk/core/src/test/java/org/infinispan/loaders/PassivationFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/PassivationFunctionalTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/loaders/PassivationFunctionalTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -8,7 +8,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
Modified: trunk/core/src/test/java/org/infinispan/manager/CacheManagerComponentRegistryTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/manager/CacheManagerComponentRegistryTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/manager/CacheManagerComponentRegistryTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -8,10 +8,10 @@
import org.infinispan.eviction.EvictionStrategy;
import org.infinispan.interceptors.BatchingInterceptor;
import org.infinispan.interceptors.InterceptorChain;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManager;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.tm.DummyTransactionManager;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
Modified: trunk/core/src/test/java/org/infinispan/manager/CacheManagerXmlConfigurationTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/manager/CacheManagerXmlConfigurationTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/manager/CacheManagerXmlConfigurationTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -4,7 +4,7 @@
import org.infinispan.test.TestingUtil;
import org.infinispan.config.Configuration;
import org.infinispan.config.DuplicateCacheNameException;
-import org.infinispan.remoting.RpcManager;
+import org.infinispan.remoting.rpc.RpcManager;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
@@ -97,7 +97,7 @@
" </default>\n" +
"\n" +
" <namedCache name=\"c1\">\n" +
- " <transaction transactionManagerLookupClass=\"org.infinispan.transaction.GenericTransactionManagerLookup\"/>\n" +
+ " <transaction transactionManagerLookupClass=\"org.infinispan.transaction.lookup.GenericTransactionManagerLookup\"/>\n" +
" </namedCache>\n" +
"\n" +
"</infinispan>";
Modified: trunk/core/src/test/java/org/infinispan/marshall/MarshalledValueTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/MarshalledValueTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/marshall/MarshalledValueTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,6 +1,5 @@
package org.infinispan.marshall;
-import org.infinispan.AdvancedCache;
import org.infinispan.Cache;
import org.infinispan.CacheException;
import org.infinispan.commands.write.PutKeyValueCommand;
@@ -66,8 +65,10 @@
@BeforeMethod
public void addMarshalledValueInterceptor() {
+ InterceptorChain chain = TestingUtil.extractComponent(cache1, InterceptorChain.class);
+ chain.removeInterceptor(MarshalledValueListenerInterceptor.class);
mvli = new MarshalledValueListenerInterceptor();
- ((AdvancedCache) cache1).addInterceptorAfter(mvli, MarshalledValueInterceptor.class);
+ chain.addInterceptorAfter(mvli, MarshalledValueInterceptor.class);
}
@AfterMethod
@@ -116,8 +117,11 @@
}
public void testReleaseObjectValueReferences() {
+ assert cache1.isEmpty();
Pojo value = new Pojo();
+ System.out.println(TestingUtil.extractComponent(cache1, InterceptorChain.class).toString());
cache1.put("key", value);
+ assert cache1.containsKey("key");
assertSerializationCounts(1, 0);
DataContainer dc1 = TestingUtil.extractComponent(cache1, DataContainer.class);
@@ -280,7 +284,7 @@
cache1.put("key", pojo);
assert l.newValue != null;
- assert l.newValue instanceof MarshalledValue;
+ assert l.newValue instanceof MarshalledValue : "recieved " + l.newValue.getClass().getName();
MarshalledValue mv = (MarshalledValue) l.newValue;
assert mv.instance instanceof Pojo;
assertSerializationCounts(1, 0);
Modified: trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -21,18 +21,6 @@
*/
package org.infinispan.marshall;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
import org.infinispan.commands.RemoteCommandFactory;
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.commands.control.StateTransferControlCommand;
@@ -61,8 +49,8 @@
import org.infinispan.remoting.responses.UnsuccessfulResponse;
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
-import org.infinispan.transaction.GlobalTransaction;
import org.infinispan.transaction.TransactionLog;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.FastCopyHashMap;
import org.infinispan.util.Immutables;
import org.jgroups.stack.IpAddress;
@@ -70,6 +58,8 @@
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
+import java.util.*;
+
/**
* Test for home grown and JBoss Marshalling based marshallers where data written
* and size of payloads are compared. It's disabled by default because JBoss
@@ -102,7 +92,7 @@
}
public void testGlobalTransactionMarshalling() throws Exception {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(12345)), false);
checkEqualityAndSize(gtx);
}
@@ -110,7 +100,7 @@
List l1 = new ArrayList();
List l2 = new LinkedList();
for (int i = 0; i < 10; i++) {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(1000 * i)), false);
l1.add(gtx);
l2.add(gtx);
}
@@ -124,7 +114,7 @@
Map m3 = new HashMap();
Map<Integer, GlobalTransaction> m4 = new FastCopyHashMap<Integer, GlobalTransaction>();
for (int i = 0; i < 10; i++) {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(1000 * i)), false);
m1.put(1000 * i, gtx);
m2.put(1000 * i, gtx);
m4.put(1000 * i, gtx);
@@ -160,19 +150,19 @@
}
public void testMarshalledValueMarshalling() throws Exception {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(12345)), false);
MarshalledValue mv = new MarshalledValue(gtx, true);
checkEqualityAndSize(mv);
}
public void testSingletonListMarshalling() throws Exception {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(12345)), false);
List l = Collections.singletonList(gtx);
checkEqualityAndSize(l);
}
public void testTransactionLogMarshalling() throws Exception {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(12345)), false);
PutKeyValueCommand command = new PutKeyValueCommand("k", "v", false, null, 0, 0);
TransactionLog.LogEntry entry = new TransactionLog.LogEntry(gtx, command);
@@ -286,15 +276,15 @@
Map m1 = new HashMap();
for (int i = 0; i < 10; i++) {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(1000 * i)), false);
m1.put(1000 * i, gtx);
}
PutMapCommand c10 = new PutMapCommand(m1, null, 0, 0);
checkEqualityAndSize(c10);
Address local = new JGroupsAddress(new IpAddress(12345));
- GlobalTransaction gtx = GlobalTransaction.create(local);
- PrepareCommand c11 = new PrepareCommand(gtx, local, true, c5, c6, c8, c10);
+ GlobalTransaction gtx = new GlobalTransaction(local, false);
+ PrepareCommand c11 = new PrepareCommand(gtx, true, c5, c6, c8, c10);
checkEqualityAndSize(c11);
CommitCommand c12 = new CommitCommand(gtx);
Modified: trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -49,8 +49,8 @@
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
import org.infinispan.statetransfer.Person;
-import org.infinispan.transaction.GlobalTransaction;
import org.infinispan.transaction.TransactionLog;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.FastCopyHashMap;
import org.infinispan.util.Immutables;
import org.jgroups.stack.IpAddress;
@@ -89,7 +89,8 @@
}
public void testGlobalTransactionMarshalling() throws Exception {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ JGroupsAddress jGroupsAddress = new JGroupsAddress(new IpAddress(12345));
+ GlobalTransaction gtx = new GlobalTransaction(jGroupsAddress, false);
marshallAndAssertEquality(gtx);
}
@@ -97,7 +98,8 @@
List l1 = new ArrayList();
List l2 = new LinkedList();
for (int i = 0; i < 10; i++) {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ JGroupsAddress jGroupsAddress = new JGroupsAddress(new IpAddress(1000 * i));
+ GlobalTransaction gtx = new GlobalTransaction(jGroupsAddress, false);
l1.add(gtx);
l2.add(gtx);
}
@@ -111,7 +113,8 @@
Map m3 = new HashMap();
Map<Integer, GlobalTransaction> m4 = new FastCopyHashMap<Integer, GlobalTransaction>();
for (int i = 0; i < 10; i++) {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ JGroupsAddress jGroupsAddress = new JGroupsAddress(new IpAddress(1000 * i));
+ GlobalTransaction gtx = new GlobalTransaction(jGroupsAddress, false);
m1.put(1000 * i, gtx);
m2.put(1000 * i, gtx);
m4.put(1000 * i, gtx);
@@ -148,13 +151,13 @@
}
public void testSingletonListMarshalling() throws Exception {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(12345)), false);
List l = Collections.singletonList(gtx);
marshallAndAssertEquality(l);
}
public void testTransactionLogMarshalling() throws Exception {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(12345)), false);
PutKeyValueCommand command = new PutKeyValueCommand("k", "v", false, null, 0, 0);
TransactionLog.LogEntry entry = new TransactionLog.LogEntry(gtx, command);
byte[] bytes = marshaller.objectToByteBuffer(entry);
@@ -191,7 +194,7 @@
ClusteredGetCommand c2 = new ClusteredGetCommand("key", "mycache");
marshallAndAssertEquality(c2);
- // SizeCommand does not have an empty constructor, so doesn't look to be one that is marshallable.
+ // SizeCommand does not have an empty constructor, so doesn't look to be one that is marshallable.
GetKeyValueCommand c4 = new GetKeyValueCommand("key", null);
bytes = marshaller.objectToByteBuffer(c4);
@@ -230,15 +233,15 @@
Map m1 = new HashMap();
for (int i = 0; i < 10; i++) {
- GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ GlobalTransaction gtx = new GlobalTransaction(new JGroupsAddress(new IpAddress(1000 * i)), false);
m1.put(1000 * i, gtx);
}
PutMapCommand c10 = new PutMapCommand(m1, null, 0, 0);
marshallAndAssertEquality(c10);
Address local = new JGroupsAddress(new IpAddress(12345));
- GlobalTransaction gtx = GlobalTransaction.create(local);
- PrepareCommand c11 = new PrepareCommand(gtx, local, true, c5, c6, c8, c10);
+ GlobalTransaction gtx = new GlobalTransaction(local, false);
+ PrepareCommand c11 = new PrepareCommand(gtx, true, c5, c6, c8, c10);
marshallAndAssertEquality(c11);
CommitCommand c12 = new CommitCommand(gtx);
Modified: trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -1,23 +1,22 @@
package org.infinispan.notifications.cachelistener;
import org.easymock.EasyMock;
-import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.classextension.EasyMock.createNiceMock;
import org.infinispan.Cache;
import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextContainer;
-import org.infinispan.context.InvocationContextImpl;
-import org.infinispan.factories.context.DefaultContextFactory;
+import org.infinispan.context.container.InvocationContextContainer;
+import org.infinispan.context.container.ReplicationInvocationContextContainer;
+import org.infinispan.context.impl.NonTxInvocationContext;
import org.infinispan.notifications.cachelistener.event.CacheEntryEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
import org.infinispan.notifications.cachelistener.event.Event;
import org.infinispan.notifications.cachelistener.event.TransactionCompletedEvent;
import org.infinispan.notifications.cachelistener.event.TransactionRegisteredEvent;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import javax.transaction.Transaction;
-
@Test(groups = "unit", testName = "notifications.cachelistener.CacheNotifierImplTest")
public class CacheNotifierImplTest {
CacheNotifierImpl n;
@@ -30,13 +29,12 @@
n = new CacheNotifierImpl();
mockCache = createNiceMock(Cache.class);
EasyMock.replay(mockCache);
- InvocationContextContainer icc = new InvocationContextContainer();
- icc.injectContextFactory(new DefaultContextFactory());
+ InvocationContextContainer icc = new ReplicationInvocationContextContainer();
n.injectDependencies(icc, mockCache);
cl = new CacheListener();
n.start();
n.addListener(cl);
- ctx = new InvocationContextImpl();
+ ctx = new NonTxInvocationContext();
}
public void testNotifyCacheEntryCreated() {
@@ -180,7 +178,7 @@
}
public void testNotifyTransactionCompleted() {
- Transaction tx = createNiceMock(Transaction.class);
+ GlobalTransaction tx = createNiceMock(GlobalTransaction.class);
n.notifyTransactionCompleted(tx, true, ctx);
n.notifyTransactionCompleted(tx, false, ctx);
@@ -188,25 +186,25 @@
assert cl.getEvents().get(0).getCache() == mockCache;
assert cl.getEvents().get(0).getType() == Event.Type.TRANSACTION_COMPLETED;
assert ((TransactionCompletedEvent) cl.getEvents().get(0)).isTransactionSuccessful();
- assert ((TransactionCompletedEvent) cl.getEvents().get(0)).getTransaction() == tx;
+ assert ((TransactionCompletedEvent) cl.getEvents().get(0)).getGlobalTransaction() == tx;
assert cl.getEvents().get(1).getCache() == mockCache;
assert cl.getEvents().get(1).getType() == Event.Type.TRANSACTION_COMPLETED;
assert !((TransactionCompletedEvent) cl.getEvents().get(1)).isTransactionSuccessful();
- assert ((TransactionCompletedEvent) cl.getEvents().get(1)).getTransaction() == tx;
+ assert ((TransactionCompletedEvent) cl.getEvents().get(1)).getGlobalTransaction() == tx;
}
public void testNotifyTransactionRegistered() {
- InvocationContext ctx = new InvocationContextImpl();
- Transaction tx = createNiceMock(Transaction.class);
+ InvocationContext ctx = new NonTxInvocationContext();
+ GlobalTransaction tx = createNiceMock(GlobalTransaction.class);
n.notifyTransactionRegistered(tx, ctx);
n.notifyTransactionRegistered(tx, ctx);
assert cl.getInvocationCount() == 2;
assert cl.getEvents().get(0).getCache() == mockCache;
assert cl.getEvents().get(0).getType() == Event.Type.TRANSACTION_REGISTERED;
- assert ((TransactionRegisteredEvent) cl.getEvents().get(0)).getTransaction() == tx;
+ assert ((TransactionRegisteredEvent) cl.getEvents().get(0)).getGlobalTransaction() == tx;
assert cl.getEvents().get(1).getCache() == mockCache;
assert cl.getEvents().get(1).getType() == Event.Type.TRANSACTION_REGISTERED;
- assert ((TransactionRegisteredEvent) cl.getEvents().get(1)).getTransaction() == tx;
+ assert ((TransactionRegisteredEvent) cl.getEvents().get(1)).getGlobalTransaction() == tx;
}
}
Modified: trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -7,14 +7,14 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.concurrent.IsolationLevel;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import java.util.Collections;
import java.util.HashMap;
@@ -66,7 +66,7 @@
cache.putAll(data);
verify(mockNotifier);
- // now reset the mock
+ // now resume the mock
reset(mockNotifier);
}
@@ -82,9 +82,9 @@
}
private void expectTransactionBoundaries(boolean successful) {
- mockNotifier.notifyTransactionRegistered(isA(Transaction.class), isA(InvocationContext.class));
+ mockNotifier.notifyTransactionRegistered(isA(GlobalTransaction.class), isA(InvocationContext.class));
expectLastCall().once();
- mockNotifier.notifyTransactionCompleted(isA(Transaction.class), eq(successful), isA(InvocationContext.class));
+ mockNotifier.notifyTransactionCompleted(isA(GlobalTransaction.class), eq(successful), isA(InvocationContext.class));
expectLastCall().once();
}
Modified: trunk/core/src/test/java/org/infinispan/replication/AsyncReplTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/replication/AsyncReplTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/replication/AsyncReplTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -12,7 +12,7 @@
import org.infinispan.config.Configuration;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import static org.testng.AssertJUnit.assertEquals;
import org.testng.annotations.Test;
@@ -59,21 +59,21 @@
replListener(cache2).expectAny();
cache1.put(key, "value1");
// allow for replication
- replListener(cache2).waitForRpc(60, TimeUnit.SECONDS);
+ replListener(cache2).waitForRpc();
+ assertNotLocked(cache1, key);
+
assertEquals("value1", cache1.get(key));
assertEquals("value1", cache2.get(key));
TransactionManager mgr = TestingUtil.getTransactionManager(cache1);
mgr.begin();
-
replListener(cache2).expectAnyWithTx();
cache1.put(key, "value2");
assertEquals("value2", cache1.get(key));
assertEquals("value1", cache2.get(key));
-
mgr.commit();
-
replListener(cache2).waitForRpc(60, TimeUnit.SECONDS);
+ assertNotLocked(cache1, key);
assertEquals("value2", cache1.get(key));
assertEquals("value2", cache2.get(key));
@@ -87,5 +87,20 @@
assertEquals("value2", cache1.get(key));
assertEquals("value2", cache2.get(key));
+
+ assertNotLocked(cache1, key);
+
}
+
+ public void simpleTest() throws Exception {
+ String key = "key";
+ TransactionManager mgr = TestingUtil.getTransactionManager(cache1);
+
+ mgr.begin();
+ cache1.put(key, "value3");
+ mgr.rollback();
+
+ assertNotLocked(cache1, key);
+
+ }
}
Modified: trunk/core/src/test/java/org/infinispan/replication/BaseReplicatedAPITest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/replication/BaseReplicatedAPITest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/replication/BaseReplicatedAPITest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -2,15 +2,15 @@
import org.infinispan.AdvancedCache;
import org.infinispan.Cache;
+import org.infinispan.context.Flag;
import org.infinispan.commands.write.ClearCommand;
import org.infinispan.commands.write.PutKeyValueCommand;
import org.infinispan.commands.write.PutMapCommand;
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.config.Configuration;
-import org.infinispan.context.Flag;
import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import java.util.HashMap;
import java.util.List;
Modified: trunk/core/src/test/java/org/infinispan/replication/ReplicationExceptionTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/replication/ReplicationExceptionTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/replication/ReplicationExceptionTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -15,7 +15,7 @@
import org.infinispan.interceptors.base.CommandInterceptor;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.infinispan.util.concurrent.TimeoutException;
import static org.testng.AssertJUnit.assertNotNull;
Modified: trunk/core/src/test/java/org/infinispan/replication/ReplicationQueueTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/replication/ReplicationQueueTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/replication/ReplicationQueueTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -9,7 +9,7 @@
import org.infinispan.remoting.ReplicationQueue;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.Test;
import javax.transaction.TransactionManager;
Modified: trunk/core/src/test/java/org/infinispan/replication/SyncCacheListenerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/replication/SyncCacheListenerTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/replication/SyncCacheListenerTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -17,8 +17,9 @@
import org.infinispan.notifications.cachelistener.event.TransactionalEvent;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
+import org.infinispan.util.concurrent.locks.LockManager;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import static org.testng.AssertJUnit.*;
@@ -134,16 +135,20 @@
public void testSyncReplMap() throws Exception {
Integer age;
+ LockManager lm1 = TestingUtil.extractComponent(cache1, LockManager.class);
+ assert lm1.getOwner("age") == null : "lock info is " + lm1.printLockInfo();
LocalListener lis = new LocalListener();
cache1.addListener(lis);
lis.put("age", 38);
+ assert lm1.getOwner("age") == null : "lock info is " + lm1.printLockInfo();
cache1.put("name", "Ben");
// value on cache2 must be 38
age = (Integer) cache2.get("age");
assertNotNull("\"age\" obtained from cache2 must be non-null ", age);
assertTrue("\"age\" must be 38", age == 38);
+ assert lm1.getOwner("age") == null : "lock info is " + lm1.printLockInfo();
}
@Listener
Modified: trunk/core/src/test/java/org/infinispan/replication/SyncReplTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/replication/SyncReplTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/replication/SyncReplTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -10,10 +10,10 @@
import org.infinispan.Cache;
import org.infinispan.commands.remote.CacheRpcCommand;
import org.infinispan.config.Configuration;
-import org.infinispan.remoting.ResponseFilter;
-import org.infinispan.remoting.ResponseMode;
-import org.infinispan.remoting.RpcManager;
-import org.infinispan.remoting.RpcManagerImpl;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.remoting.rpc.RpcManagerImpl;
import org.infinispan.remoting.responses.Response;
import org.infinispan.remoting.transport.Address;
import org.infinispan.remoting.transport.Transport;
@@ -150,7 +150,7 @@
// check that the replication call was sync
cache1.put("k", "v");
- // reset to test for async
+ // resume to test for async
reset(mockTransport);
expect(mockTransport.getAddress()).andReturn(mockAddressOne).anyTimes();
expect(mockTransport.getMembers()).andReturn(addresses).anyTimes();
Modified: trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferCacheLoaderFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferCacheLoaderFunctionalTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferCacheLoaderFunctionalTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -10,7 +10,7 @@
import org.infinispan.test.TestingUtil;
import org.testng.annotations.Test;
- at Test(groups = "functional", testName = "statetransfer.StateTransferCacheLoaderFunctionalTest")
+ at Test(groups = "functional", testName = "statetransfer.StateTransferCacheLoaderFunctionalTest", enabled = false)
public class StateTransferCacheLoaderFunctionalTest extends StateTransferFunctionalTest {
int id;
ThreadLocal<Boolean> sharedCacheLoader = new ThreadLocal<Boolean>() {
Modified: trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferFunctionalTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferFunctionalTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferFunctionalTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -5,7 +5,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import org.testng.annotations.Test;
@@ -16,7 +16,7 @@
import java.io.ObjectOutputStream;
import java.io.Serializable;
- at Test(groups = "functional", testName = "statetransfer.StateTransferFunctionalTest")
+ at Test(groups = "functional", testName = "statetransfer.StateTransferFunctionalTest", enabled = false)
public class StateTransferFunctionalTest extends MultipleCacheManagersTest {
protected static final String ADDRESS_CLASSNAME = Address.class.getName();
Modified: trunk/core/src/test/java/org/infinispan/test/AbstractCacheTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/AbstractCacheTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/test/AbstractCacheTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -46,8 +46,7 @@
removeInMemoryData(cache);
clearCacheLoader(cache);
clearReplicationQueues(cache);
- InvocationContext invocationContext = ((AdvancedCache) cache).getInvocationContextContainer().get();
- if (invocationContext != null) invocationContext.reset();
+ InvocationContext invocationContext = ((AdvancedCache) cache).getInvocationContextContainer().getLocalInvocationContext(true);
}
}
}
Modified: trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -4,6 +4,7 @@
import org.infinispan.config.Configuration;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.util.concurrent.locks.LockManager;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
@@ -82,6 +83,7 @@
}
} else {
TestingUtil.killCacheManagers(cacheManagers);
+ cacheManagers.clear();
}
}
@@ -168,4 +170,10 @@
* {@link #addClusterEnabledCacheManager()}
*/
protected abstract void createCacheManagers() throws Throwable;
+
+
+ protected void assertNotLocked(Cache cache, Object key) {
+ LockManager lockManager = TestingUtil.extractLockManager(cache);
+ assert !lockManager.isLocked(key) : "expected key '" + key + "' not to be locked, and it is by: " + lockManager.getOwner(key);
+ }
}
Modified: trunk/core/src/test/java/org/infinispan/test/ReplListener.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/ReplListener.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/test/ReplListener.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -6,6 +6,7 @@
import org.infinispan.commands.tx.PrepareCommand;
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.interceptors.base.CommandInterceptor;
import java.util.Arrays;
@@ -166,13 +167,17 @@
@Override
protected Object handleDefault(InvocationContext ctx, VisitableCommand cmd) throws Throwable {
// first pass up chain
- Object o = invokeNextInterceptor(ctx, cmd);
- if (!ctx.isOriginLocal() || watchLocal) markAsVisited(cmd);
+ Object o;
+ try {
+ o = invokeNextInterceptor(ctx, cmd);
+ } finally {//make sure we do mark this command as received even in the case of exceptions(e.g. timeouts)
+ if (!ctx.isOriginLocal() || watchLocal) markAsVisited(cmd);
+ }
return o;
}
@Override
- public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand cmd) throws Throwable {
+ public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand cmd) throws Throwable {
// first pass up chain
Object o = invokeNextInterceptor(ctx, cmd);
if (!ctx.isOriginLocal() || watchLocal) {
@@ -185,7 +190,7 @@
private void markAsVisited(VisitableCommand cmd) {
expectationSetupLock.lock();
try {
- log.fatal("Cache [" + c + "] saw command " + cmd);
+ log.info("Cache [" + c + "] saw command " + cmd);
if (expectedCommands != null) {
expectedCommands.remove(cmd.getClass());
sawAtLeastOneInvocation = true;
Modified: trunk/core/src/test/java/org/infinispan/test/TestingUtil.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/TestingUtil.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/test/TestingUtil.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -12,6 +12,8 @@
import org.infinispan.CacheDelegate;
import org.infinispan.commands.CommandsFactory;
import org.infinispan.commands.VisitableCommand;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.factories.GlobalComponentRegistry;
import org.infinispan.interceptors.InterceptorChain;
@@ -123,10 +125,10 @@
/**
* Waits for the given memebrs to be removed from the cluster. The difference between this and {@link
- * #blockUntilViewsReceived(long, org.infinispan.manager.CacheManager[])} methods(s) is that it does not barf if more
- * than expected memebers is in the cluster - this is because we expect to start with a grater number fo memebers
- * than we eventually expect. It will barf though, if the number of members is not the one expected but only after
- * the timeout expieres.
+ * #blockUntilViewsReceived(long, org.infinispan.manager.CacheManager[])} methods(s) is that it does not barf if
+ * more than expected memebers is in the cluster - this is because we expect to start with a grater number fo
+ * memebers than we eventually expect. It will barf though, if the number of members is not the one expected but
+ * only after the timeout expieres.
*/
public static void blockForMemberToFail(long timeout, CacheManager... cacheManagers) {
blockUntilViewsReceived(timeout, false, cacheManagers);
@@ -520,14 +522,15 @@
public static void replicateCommand(Cache cache, VisitableCommand command) throws Throwable {
ComponentRegistry cr = extractComponentRegistry(cache);
InterceptorChain ic = cr.getComponent(InterceptorChain.class);
- ic.invoke(command);
+ InvocationContextContainer icc = cr.getComponent(InvocationContextContainer.class);
+ InvocationContext ctxt = icc.getLocalInvocationContext(true);
+ ic.invoke(ctxt, command);
}
public static void blockUntilViewsReceived(int timeout, List caches) {
blockUntilViewsReceived((Cache[]) caches.toArray(new Cache[]{}), timeout);
}
-
public static CommandsFactory extractCommandsFactory(Cache<Object, Object> cache) {
return (CommandsFactory) extractField(cache, "commandsFactory");
}
Modified: trunk/core/src/test/java/org/infinispan/tx/LocalModeTxTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/LocalModeTxTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/tx/LocalModeTxTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -27,7 +27,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.SingleCacheManagerTest;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.Test;
import javax.transaction.Transaction;
@@ -58,6 +58,19 @@
assert !c.isEmpty();
}
+ public void testTxCommit3() throws Exception {
+ TransactionManager tm = TestingUtil.getTransactionManager(c);
+ tm.begin();
+ c.put("key", "value");
+ tm.commit();
+ assert !c.isEmpty();
+ }
+
+ public void testNonTx() throws Exception {
+ c.put("key", "value");
+ assert !c.isEmpty();
+ }
+
public void testTxCommit2() throws Exception {
TransactionManager tm = TestingUtil.getTransactionManager(c);
c.put("key", "old");
Modified: trunk/core/src/test/java/org/infinispan/tx/MarkAsRollbackTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/MarkAsRollbackTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/tx/MarkAsRollbackTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -5,7 +5,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.Test;
import javax.transaction.RollbackException;
Modified: trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningCaches.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningCaches.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningCaches.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -6,7 +6,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.Test;
import javax.transaction.Transaction;
Modified: trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningReplicatedCaches.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningReplicatedCaches.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/java/org/infinispan/tx/TransactionsSpanningReplicatedCaches.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -5,7 +5,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.testng.annotations.Test;
import javax.transaction.Transaction;
@@ -137,4 +137,35 @@
assert c2.get("c2key").equals("c2value");
assert c2Replica.get("c2key").equals("c2value");
}
+
+ public void testRollbackSpanningCaches2() throws Exception {
+ Cache c1 = cm1.getCache("c1");
+
+ assert c1.getConfiguration().getCacheMode().isClustered();
+ Cache c1Replica = cm2.getCache("c1");
+
+ assert c1.isEmpty();
+ assert c1Replica.isEmpty();
+
+ c1.put("c1key", "c1value");
+ assert c1.get("c1key").equals("c1value");
+ assert c1Replica.get("c1key").equals("c1value");
+ }
+
+ public void testSimpleCommit() throws Exception {
+ Cache c1 = cm1.getCache("c1");
+ Cache c1Replica = cm2.getCache("c1");
+
+
+ assert c1.isEmpty();
+ assert c1Replica.isEmpty();
+
+ TransactionManager tm = TestingUtil.getTransactionManager(c1);
+ tm.begin();
+ c1.put("c1key", "c1value");
+ tm.commit();
+
+ assert c1.get("c1key").equals("c1value");
+ assert c1Replica.get("c1key").equals("c1value");
+ }
}
\ No newline at end of file
Modified: trunk/core/src/test/resources/configs/named-cache-test.xml
===================================================================
--- trunk/core/src/test/resources/configs/named-cache-test.xml 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/resources/configs/named-cache-test.xml 2009-05-12 02:58:05 UTC (rev 252)
@@ -37,7 +37,7 @@
</default>
<namedCache name="transactional">
- <transaction transactionManagerLookupClass="org.infinispan.transaction.GenericTransactionManagerLookup"/>
+ <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"/>
</namedCache>
<namedCache name="syncRepl">
Modified: trunk/core/src/test/resources/configs/string-property-replaced.xml
===================================================================
--- trunk/core/src/test/resources/configs/string-property-replaced.xml 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/core/src/test/resources/configs/string-property-replaced.xml 2009-05-12 02:58:05 UTC (rev 252)
@@ -30,7 +30,7 @@
concurrencyLevel="500"/>
<transaction
- transactionManagerLookupClass="org.infinispan.transaction.GenericTransactionManagerLookup"
+ transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
syncRollbackPhase="false"
syncCommitPhase="${test.property.SyncCommitPhase:true}"/>
Modified: trunk/tree/src/main/java/org/infinispan/tree/NodeImpl.java
===================================================================
--- trunk/tree/src/main/java/org/infinispan/tree/NodeImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/main/java/org/infinispan/tree/NodeImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -23,9 +23,10 @@
import org.infinispan.Cache;
import org.infinispan.atomic.AtomicMap;
+import org.infinispan.atomic.atomichashmap.AtomicHashMapProxy;
import org.infinispan.batch.BatchContainer;
import org.infinispan.context.Flag;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.util.Immutables;
import org.infinispan.util.Util;
@@ -58,19 +59,19 @@
}
public Node<K, V> getParent(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getParent();
}
public Set<Node<K, V>> getChildren() {
startAtomic();
try {
- Set<Node<K, V>> set = new HashSet<Node<K, V>>();
+ Set<Node<K, V>> result = new HashSet<Node<K, V>>();
for (Fqn f : getStructure().values()) {
NodeImpl<K, V> n = new NodeImpl<K, V>(f, cache, batchContainer, icc);
- set.add(n);
+ result.add(n);
}
- return Immutables.immutableSetWrap(set);
+ return Immutables.immutableSetWrap(result);
}
finally {
endAtomic();
@@ -78,7 +79,7 @@
}
public Set<Node<K, V>> getChildren(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getChildren();
}
@@ -87,7 +88,7 @@
}
public Set<Object> getChildrenNames(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getChildrenNames();
}
@@ -97,7 +98,7 @@
}
public Map<K, V> getData(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getData();
}
@@ -112,7 +113,7 @@
}
public Set<K> getKeys(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getKeys();
}
@@ -124,11 +125,15 @@
startAtomic();
try {
Fqn absoluteChildFqn = Fqn.fromRelativeFqn(fqn, f);
- NodeImpl<K, V> child = new NodeImpl<K, V>(absoluteChildFqn, cache, batchContainer, icc);
- AtomicMap<Object, Fqn> s = getStructure();
- s.put(f.getLastElement(), absoluteChildFqn);
+
+ //1) first register it with the parent
+ AtomicMap<Object, Fqn> structureMap = getStructure();
+ structureMap.put(f.getLastElement(), absoluteChildFqn);
+
+ //2) then create the structure and data maps
createNodeInCache(absoluteChildFqn);
- return child;
+
+ return new NodeImpl<K, V>(absoluteChildFqn, cache, batchContainer, icc);
}
finally {
endAtomic();
@@ -136,7 +141,7 @@
}
public Node<K, V> addChild(Fqn f, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return addChild(f);
}
@@ -145,7 +150,7 @@
}
public boolean removeChild(Fqn f, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return removeChild(f);
}
@@ -171,7 +176,7 @@
}
public boolean removeChild(Object childName, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return removeChild(childName);
}
@@ -189,7 +194,7 @@
}
public Node<K, V> getChild(Fqn f, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getChild(f);
}
@@ -207,14 +212,15 @@
}
public Node<K, V> getChild(Object name, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getChild(name);
}
public V put(K key, V value) {
startAtomic();
try {
- return getDataInternal().put(key, value);
+ AtomicHashMapProxy<K, V> map = (AtomicHashMapProxy<K, V>) getDataInternal();
+ return map.put(key, value);
}
finally {
endAtomic();
@@ -222,7 +228,7 @@
}
public V put(K key, V value, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return put(key, value);
}
@@ -240,14 +246,14 @@
}
public V putIfAbsent(K key, V value, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return putIfAbsent(key, value);
}
public V replace(K key, V value) {
startAtomic();
try {
- AtomicMap<K, V> map = getDataInternal();
+ AtomicMap<K, V> map = cache.getAtomicMap(dataKey);
if (map.containsKey(key))
return map.put(key, value);
else
@@ -259,7 +265,7 @@
}
public V replace(K key, V value, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return replace(key, value);
}
@@ -280,7 +286,7 @@
}
public boolean replace(K key, V oldValue, V value, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return replace(key, oldValue, value);
}
@@ -295,7 +301,7 @@
}
public void putAll(Map<? extends K, ? extends V> map, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
putAll(map);
}
@@ -312,7 +318,7 @@
}
public void replaceAll(Map<? extends K, ? extends V> map, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
replaceAll(map);
}
@@ -321,7 +327,7 @@
}
public V get(K key, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return get(key);
}
@@ -336,7 +342,7 @@
}
public V remove(K key, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return remove(key);
}
@@ -345,7 +351,7 @@
}
public void clearData(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
clearData();
}
@@ -354,7 +360,7 @@
}
public int dataSize(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return dataSize();
}
@@ -369,7 +375,7 @@
}
public boolean hasChild(Fqn f, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return hasChild(f);
}
@@ -378,7 +384,7 @@
}
public boolean hasChild(Object o, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return hasChild(o);
}
@@ -398,7 +404,7 @@
}
public void removeChildren(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
removeChildren();
}
Modified: trunk/tree/src/main/java/org/infinispan/tree/TreeCacheImpl.java
===================================================================
--- trunk/tree/src/main/java/org/infinispan/tree/TreeCacheImpl.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/main/java/org/infinispan/tree/TreeCacheImpl.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -52,7 +52,7 @@
}
public Node<K, V> getRoot(Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getRoot();
}
@@ -61,7 +61,7 @@
}
public V put(String fqn, K key, V value, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return put(fqn, key, value);
}
@@ -76,7 +76,7 @@
}
public void put(Fqn fqn, Map<? extends K, ? extends V> data, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
put(fqn, data);
}
@@ -85,7 +85,7 @@
}
public void put(String fqn, Map<? extends K, ? extends V> data, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
put(fqn, data);
}
@@ -102,7 +102,7 @@
}
public V remove(Fqn fqn, K key, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return remove(fqn, key);
}
@@ -111,7 +111,7 @@
}
public V remove(String fqn, K key, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return remove(fqn, key);
}
@@ -132,7 +132,7 @@
}
public boolean removeNode(Fqn fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return removeNode(fqn);
}
@@ -141,7 +141,7 @@
}
public boolean removeNode(String fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return removeNode(fqn);
}
@@ -158,7 +158,7 @@
}
public Node<K, V> getNode(Fqn fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getThreadContext().setFlags(flags);
return getNode(fqn);
}
@@ -167,7 +167,7 @@
}
public Node<K, V> getNode(String fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getNode(fqn);
}
@@ -179,7 +179,7 @@
}
public V get(Fqn fqn, K key, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return get(fqn, key);
}
@@ -188,12 +188,12 @@
}
public boolean exists(String fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return exists(fqn);
}
public boolean exists(Fqn fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return exists(fqn);
}
@@ -202,14 +202,13 @@
}
public V get(String fqn, K key, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return get(fqn, key);
}
public void move(Fqn nodeToMoveFqn, Fqn newParentFqn) throws NodeNotExistsException {
if (trace) log.trace("Moving node '" + nodeToMoveFqn + "' to '" + newParentFqn + "'");
- if (nodeToMoveFqn == null || newParentFqn == null)
- throw new NullPointerException("Cannot accept null parameters!");
+ if (nodeToMoveFqn == null || newParentFqn == null) throw new NullPointerException("Cannot accept null parameters!");
if (nodeToMoveFqn.getParent().equals(newParentFqn)) {
if (trace) log.trace("Not doing anything as this node is equal with its parent");
@@ -228,7 +227,7 @@
if (!exists(newParentFqn)) {
// then we need to silently create the new parent
createNodeInCache(newParentFqn);
- if (trace) log.trace("The new parent (" + newParentFqn + ") did not exists, was created");
+ if (trace) log.trace("The new parent ("+newParentFqn +") did not exists, was created");
}
// create an empty node for this new parent
@@ -252,7 +251,7 @@
}
public void move(Fqn nodeToMove, Fqn newParent, Flag... flags) throws NodeNotExistsException {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
move(nodeToMove, newParent);
}
@@ -261,7 +260,7 @@
}
public void move(String nodeToMove, String newParent, Flag... flags) throws NodeNotExistsException {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
move(nodeToMove, newParent);
}
@@ -276,7 +275,7 @@
}
public Map<K, V> getData(Fqn fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getData(fqn);
}
@@ -285,7 +284,7 @@
}
public Set<K> getKeys(String fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getKeys(fqn);
}
@@ -300,7 +299,7 @@
}
public Set<K> getKeys(Fqn fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return getKeys(fqn);
}
@@ -309,7 +308,7 @@
}
public void clearData(String fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
}
public void clearData(Fqn fqn) {
@@ -323,7 +322,7 @@
}
public void clearData(Fqn fqn, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
}
@SuppressWarnings("unchecked")
@@ -341,7 +340,7 @@
}
public V put(Fqn fqn, K key, V value, Flag... flags) {
- icc.get().setFlags(flags);
+ icc.getLocalInvocationContext(true).setFlags(flags);
return put(fqn, key, value);
}
Modified: trunk/tree/src/main/java/org/infinispan/tree/TreeStructureSupport.java
===================================================================
--- trunk/tree/src/main/java/org/infinispan/tree/TreeStructureSupport.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/main/java/org/infinispan/tree/TreeStructureSupport.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -27,7 +27,7 @@
import org.infinispan.batch.AutoBatchSupport;
import org.infinispan.batch.BatchContainer;
import org.infinispan.context.Flag;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.util.concurrent.locks.LockManager;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -35,7 +35,7 @@
public class TreeStructureSupport extends AutoBatchSupport {
private static Log log = LogFactory.getLog(TreeStructureSupport.class);
- AtomicMapCache cache;
+ AtomicMapCache<NodeKey, Object> cache;
InvocationContextContainer icc;
public TreeStructureSupport(Cache cache, BatchContainer batchContainer, InvocationContextContainer icc) {
@@ -69,7 +69,7 @@
if (!exists(parent)) createNodeInCache(parent);
AtomicMap<Object, Fqn> parentStructure = getStructure(parent);
// don't lock parents for child insert/removes!
- icc.get().setFlags(Flag.SKIP_LOCKING);
+ icc.getThreadContext().setFlags(Flag.SKIP_LOCKING);
parentStructure.put(fqn.getLastElement(), fqn);
}
cache.getAtomicMap(structureKey);
@@ -86,7 +86,7 @@
return cache.getAtomicMap(new NodeKey(fqn, NodeKey.Type.STRUCTURE));
}
- public static boolean isLocked(Cache c, LockManager lockManager, Fqn fqn) {
+ public static boolean isLocked(LockManager lockManager, Fqn fqn) {
return lockManager.isLocked(new NodeKey(fqn, NodeKey.Type.STRUCTURE)) &&
lockManager.isLocked(new NodeKey(fqn, NodeKey.Type.DATA));
}
Modified: trunk/tree/src/test/java/org/infinispan/api/tree/NodeAPITest.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/api/tree/NodeAPITest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/api/tree/NodeAPITest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -4,7 +4,7 @@
import org.infinispan.config.Configuration;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.tree.Fqn;
import org.infinispan.tree.Node;
import org.infinispan.tree.TreeCache;
Modified: trunk/tree/src/test/java/org/infinispan/api/tree/NodeLockSupport.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/api/tree/NodeLockSupport.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/api/tree/NodeLockSupport.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -50,25 +50,25 @@
protected void checkLocks() {
Cache<Object, Object> cache = cacheTL.get();
LockManager lm = TestingUtil.extractLockManager(cache);
- assert !TreeStructureSupport.isLocked(cache, lm, A);
- assert !TreeStructureSupport.isLocked(cache, lm, Fqn.ROOT);
- assert TreeStructureSupport.isLocked(cache, lm, C);
- assert TreeStructureSupport.isLocked(cache, lm, A_B);
- assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
+ assert !TreeStructureSupport.isLocked(lm, A);
+ assert !TreeStructureSupport.isLocked(lm, Fqn.ROOT);
+ assert TreeStructureSupport.isLocked(lm, C);
+ assert TreeStructureSupport.isLocked(lm, A_B);
+ assert TreeStructureSupport.isLocked(lm, A_B_C);
}
protected void checkLocksDeep() {
Cache<Object, Object> cache = cacheTL.get();
LockManager lm = TestingUtil.extractLockManager(cache);
- assert !TreeStructureSupport.isLocked(cache, lm, A);
- assert !TreeStructureSupport.isLocked(cache, lm, Fqn.ROOT);
- assert !TreeStructureSupport.isLocked(cache, lm, A_B_D);
+ assert !TreeStructureSupport.isLocked(lm, A);
+ assert !TreeStructureSupport.isLocked(lm, Fqn.ROOT);
+ assert !TreeStructureSupport.isLocked(lm, A_B_D);
- assert TreeStructureSupport.isLocked(cache, lm, C);
- assert TreeStructureSupport.isLocked(cache, lm, C_E);
- assert TreeStructureSupport.isLocked(cache, lm, A_B);
- assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
- assert TreeStructureSupport.isLocked(cache, lm, A_B_C_E);
+ assert TreeStructureSupport.isLocked(lm, C);
+ assert TreeStructureSupport.isLocked(lm, C_E);
+ assert TreeStructureSupport.isLocked(lm, A_B);
+ assert TreeStructureSupport.isLocked(lm, A_B_C);
+ assert TreeStructureSupport.isLocked(lm, A_B_C_E);
}
protected void assertNoLocks() {
Modified: trunk/tree/src/test/java/org/infinispan/api/tree/NodeMoveAPITest.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/api/tree/NodeMoveAPITest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/api/tree/NodeMoveAPITest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -3,7 +3,7 @@
import org.infinispan.api.mvcc.LockAssert;
import org.infinispan.config.Configuration;
import org.infinispan.container.DataContainer;
-import org.infinispan.context.InvocationContextContainer;
+import org.infinispan.context.container.InvocationContextContainer;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.manager.CacheManager;
import org.infinispan.test.SingleCacheManagerTest;
@@ -394,18 +394,18 @@
protected void checkLocks() {
LockManager lm = TestingUtil.extractLockManager(cache);
- assert TreeStructureSupport.isLocked(cache, lm, C);
- assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
+ assert TreeStructureSupport.isLocked(lm, C);
+ assert TreeStructureSupport.isLocked(lm, A_B_C);
}
protected void checkLocksDeep() {
LockManager lm = TestingUtil.extractLockManager(cache);
// /a/b, /c, /c/e, /a/b/c and /a/b/c/e should all be locked.
- assert TreeStructureSupport.isLocked(cache, lm, C);
- assert TreeStructureSupport.isLocked(cache, lm, C_E);
- assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
- assert TreeStructureSupport.isLocked(cache, lm, A_B_C_E);
+ assert TreeStructureSupport.isLocked(lm, C);
+ assert TreeStructureSupport.isLocked(lm, C_E);
+ assert TreeStructureSupport.isLocked(lm, A_B_C);
+ assert TreeStructureSupport.isLocked(lm, A_B_C_E);
}
protected void assertNoLocks() {
Modified: trunk/tree/src/test/java/org/infinispan/api/tree/NodeReplicatedMoveTest.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/api/tree/NodeReplicatedMoveTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/api/tree/NodeReplicatedMoveTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -10,11 +10,12 @@
import org.infinispan.config.Configuration;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.tree.Fqn;
import org.infinispan.tree.Node;
import org.infinispan.tree.TreeCache;
import org.infinispan.tree.TreeCacheImpl;
+import org.infinispan.tree.TreeStructureSupport;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
import org.testng.annotations.Test;
@@ -102,7 +103,9 @@
}
+ @Test (enabled = false)
public void testReplTxRollback() throws Exception {
+ System.out.println(TreeStructureSupport.printTree(cache1, true));
Node<Object, Object> rootNode = cache1.getRoot();
Node<Object, Object> nodeA = rootNode.addChild(A);
Node<Object, Object> nodeB = nodeA.addChild(B);
@@ -115,6 +118,8 @@
assertEquals(vA, cache2.getRoot().getChild(A).get(k));
assertEquals(vB, cache2.getRoot().getChild(A).getChild(B).get(k));
+ System.out.println(TreeStructureSupport.printTree(cache1, true));
+
// now move...
tm1.begin();
cache1.move(nodeB.getFqn(), Fqn.ROOT);
@@ -123,6 +128,7 @@
assertEquals(vB, cache1.get(B, k));
tm1.rollback();
+ System.out.println(TreeStructureSupport.printTree(cache1, true));
assertEquals(vA, cache1.getRoot().getChild(A).get(k));
assertEquals(vB, cache1.getRoot().getChild(A).getChild(B).get(k));
Modified: trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTest.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -8,8 +8,8 @@
package org.infinispan.api.tree;
import org.infinispan.Cache;
+import org.infinispan.context.Flag;
import org.infinispan.config.Configuration;
-import org.infinispan.context.Flag;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.tree.Fqn;
import org.infinispan.tree.Node;
Modified: trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTxTest.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTxTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/api/tree/SyncReplTxTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -11,7 +11,7 @@
import org.infinispan.config.Configuration;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.tree.Fqn;
import org.infinispan.tree.Node;
import org.infinispan.tree.TreeCache;
Modified: trunk/tree/src/test/java/org/infinispan/api/tree/TreeCacheAPITest.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/api/tree/TreeCacheAPITest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/api/tree/TreeCacheAPITest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -7,7 +7,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
import org.infinispan.tree.Fqn;
import org.infinispan.tree.Node;
import org.infinispan.tree.NodeKey;
Modified: trunk/tree/src/test/java/org/infinispan/profiling/TreeProfileTest.java
===================================================================
--- trunk/tree/src/test/java/org/infinispan/profiling/TreeProfileTest.java 2009-05-12 01:20:29 UTC (rev 251)
+++ trunk/tree/src/test/java/org/infinispan/profiling/TreeProfileTest.java 2009-05-12 02:58:05 UTC (rev 252)
@@ -9,7 +9,7 @@
import org.infinispan.profiling.testinternals.TaskRunner;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.TreeTestingUtil;
-import org.infinispan.transaction.DummyTransactionManager;
+import org.infinispan.transaction.tm.DummyTransactionManager;
import org.infinispan.tree.Fqn;
import org.infinispan.tree.TreeCache;
import org.infinispan.tree.TreeCacheImpl;
More information about the infinispan-commits
mailing list