HHH-9868, HHH-9881 Replaced access to TransactionManager with Session

This commit is contained in:
Radim Vansa 2015-08-04 11:24:26 +02:00 committed by Galder Zamarreño
parent 1f24fa6354
commit 984125e87e
11 changed files with 199 additions and 202 deletions

View File

@ -24,6 +24,7 @@ dependencies {
testCompile( libraries.jnp_client ) testCompile( libraries.jnp_client )
testCompile( libraries.jnp_server ) testCompile( libraries.jnp_server )
testCompile( libraries.rhq ) testCompile( libraries.rhq )
testCompile( libraries.mockito )
testCompile ('mysql:mysql-connector-java:5.1.17') testCompile ('mysql:mysql-connector-java:5.1.17')
} }

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.cache.infinispan.access; package org.hibernate.cache.infinispan.access;
import javax.transaction.RollbackException;
import javax.transaction.Status; import javax.transaction.Status;
import javax.transaction.SystemException; import javax.transaction.SystemException;
import javax.transaction.Transaction; import javax.transaction.Transaction;
@ -24,7 +23,6 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cache.infinispan.util.CacheCommandInitializer; import org.hibernate.cache.infinispan.util.CacheCommandInitializer;
import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.RegionFactory;
@ -53,9 +51,9 @@ import org.infinispan.util.logging.LogFactory;
* not find data is: * not find data is:
* <p/> * <p/>
* <ol> * <ol>
* <li> Call {@link #registerPendingPut(Object, long)}</li> * <li> Call {@link #registerPendingPut(SessionImplementor, Object, long)}</li>
* <li> Read the database</li> * <li> Read the database</li>
* <li> Call {@link #acquirePutFromLoadLock(Object, long)} * <li> Call {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)}
* <li> if above returns <code>null</code>, the thread should not cache the data; * <li> if above returns <code>null</code>, the thread should not cache the data;
* only if above returns instance of <code>AcquiredLock</code>, put data in the cache and...</li> * only if above returns instance of <code>AcquiredLock</code>, put data in the cache and...</li>
* <li> then call {@link #releasePutFromLoadLock(Object, Lock)}</li> * <li> then call {@link #releasePutFromLoadLock(Object, Lock)}</li>
@ -68,18 +66,18 @@ import org.infinispan.util.logging.LogFactory;
* call * call
* <p/> * <p/>
* <ul> * <ul>
* <li> {@link #beginInvalidatingKey(Object)} (for a single key invalidation)</li> * <li> {@link #beginInvalidatingKey(SessionImplementor, Object)} (for a single key invalidation)</li>
* <li>or {@link #beginInvalidatingRegion()} followed by {@link #endInvalidatingRegion()} * <li>or {@link #beginInvalidatingRegion()} followed by {@link #endInvalidatingRegion()}
* (for a general invalidation all pending puts)</li> * (for a general invalidation all pending puts)</li>
* </ul> * </ul>
* After transaction commit (when the DB is updated) {@link #endInvalidatingKey(Object)} should * After transaction commit (when the DB is updated) {@link #endInvalidatingKey(SessionImplementor, Object)} should
* be called in order to allow further attempts to cache entry. * be called in order to allow further attempts to cache entry.
* </p> * </p>
* <p/> * <p/>
* <p> * <p>
* This class also supports the concept of "naked puts", which are calls to * This class also supports the concept of "naked puts", which are calls to
* {@link #acquirePutFromLoadLock(Object, long)} without a preceding {@link #registerPendingPut(Object, long)}. * {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)} without a preceding {@link #registerPendingPut(SessionImplementor, Object, long)}.
* Besides not acquiring lock in {@link #registerPendingPut(Object, long)} this can happen when collection * Besides not acquiring lock in {@link #registerPendingPut(SessionImplementor, Object, long)} this can happen when collection
* elements are loaded after the collection has not been found in the cache, where the elements * elements are loaded after the collection has not been found in the cache, where the elements
* don't have their own table but can be listed as 'select ... from Element where collection_id = ...'. * don't have their own table but can be listed as 'select ... from Element where collection_id = ...'.
* Naked puts are handled according to txTimestamp obtained by calling {@link RegionFactory#nextTimestamp()} * Naked puts are handled according to txTimestamp obtained by calling {@link RegionFactory#nextTimestamp()}
@ -247,20 +245,15 @@ public class PutFromLoadValidator {
} }
public void setCurrentSession(SessionImplementor session) { public void setCurrentSession(SessionImplementor session) {
// we register synchronizations directly on JTA transactions, let's make this noop with TM
if (transactionManager == null) {
currentSession.set(session); currentSession.set(session);
} }
}
public void resetCurrentSession() { public void resetCurrentSession() {
if (transactionManager == null) {
currentSession.remove(); currentSession.remove();
} }
}
/** /**
* Marker for lock acquired in {@link #acquirePutFromLoadLock(Object, long)} * Marker for lock acquired in {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)}
*/ */
public static abstract class Lock { public static abstract class Lock {
private Lock() {} private Lock() {}
@ -274,13 +267,14 @@ public class PutFromLoadValidator {
* should always be matched with a call to {@link #releasePutFromLoadLock(Object, Lock)}. * should always be matched with a call to {@link #releasePutFromLoadLock(Object, Lock)}.
* </p> * </p>
* *
* @param session
* @param key the key * @param key the key
* *
* @param txTimestamp * @param txTimestamp
* @return <code>AcquiredLock</code> if the lock is acquired and the cache put * @return <code>AcquiredLock</code> if the lock is acquired and the cache put
* can proceed; <code>null</code> if the data should not be cached * can proceed; <code>null</code> if the data should not be cached
*/ */
public Lock acquirePutFromLoadLock(Object key, long txTimestamp) { public Lock acquirePutFromLoadLock(SessionImplementor session, Object key, long txTimestamp) {
if (trace) { if (trace) {
log.tracef("acquirePutFromLoadLock(%s#%s, %d)", cache.getName(), key, txTimestamp); log.tracef("acquirePutFromLoadLock(%s#%s, %d)", cache.getName(), key, txTimestamp);
} }
@ -305,7 +299,7 @@ public class PutFromLoadValidator {
} }
continue; continue;
} }
final PendingPut toCancel = pending.remove(getLocalLockOwner()); final PendingPut toCancel = pending.remove(session);
if (toCancel != null) { if (toCancel != null) {
valid = !toCancel.completed; valid = !toCancel.completed;
toCancel.completed = true; toCancel.completed = true;
@ -359,7 +353,7 @@ public class PutFromLoadValidator {
} }
} }
PendingPut pendingPut = new PendingPut(getLocalLockOwner()); PendingPut pendingPut = new PendingPut(session);
pending = new PendingPutMap(pendingPut); pending = new PendingPutMap(pendingPut);
PendingPutMap existing = pendingPuts.putIfAbsent(key, pending); PendingPutMap existing = pendingPuts.putIfAbsent(key, pending);
if (existing != null) { if (existing != null) {
@ -388,7 +382,7 @@ public class PutFromLoadValidator {
/** /**
* Releases the lock previously obtained by a call to * Releases the lock previously obtained by a call to
* {@link #acquirePutFromLoadLock(Object, long)}. * {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)}.
* *
* @param key the key * @param key the key
*/ */
@ -407,9 +401,9 @@ public class PutFromLoadValidator {
} }
/** /**
* Invalidates all {@link #registerPendingPut(Object, long) previously registered pending puts} ensuring a subsequent call to * Invalidates all {@link #registerPendingPut(SessionImplementor, Object, long) previously registered pending puts} ensuring a subsequent call to
* {@link #acquirePutFromLoadLock(Object, long)} will return <code>false</code>. <p> This method will block until any * {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)} will return <code>false</code>. <p> This method will block until any
* concurrent thread that has {@link #acquirePutFromLoadLock(Object, long) acquired the putFromLoad lock} for the any key has * concurrent thread that has {@link #acquirePutFromLoadLock(SessionImplementor, Object, long) acquired the putFromLoad lock} for the any key has
* released the lock. This allows the caller to be certain the putFromLoad will not execute after this method returns, * released the lock. This allows the caller to be certain the putFromLoad will not execute after this method returns,
* possibly caching stale data. </p> * possibly caching stale data. </p>
* *
@ -506,16 +500,17 @@ public class PutFromLoadValidator {
/** /**
* Notifies this validator that it is expected that a database read followed by a subsequent {@link * Notifies this validator that it is expected that a database read followed by a subsequent {@link
* #acquirePutFromLoadLock(Object, long)} call will occur. The intent is this method would be called following a cache miss * #acquirePutFromLoadLock(SessionImplementor, Object, long)} call will occur. The intent is this method would be called following a cache miss
* wherein it is expected that a database read plus cache put will occur. Calling this method allows the validator to * wherein it is expected that a database read plus cache put will occur. Calling this method allows the validator to
* treat the subsequent <code>acquirePutFromLoadLock</code> as if the database read occurred when this method was * treat the subsequent <code>acquirePutFromLoadLock</code> as if the database read occurred when this method was
* invoked. This allows the validator to compare the timestamp of this call against the timestamp of subsequent removal * invoked. This allows the validator to compare the timestamp of this call against the timestamp of subsequent removal
* notifications. * notifications.
* *
* @param session
* @param key key that will be used for subsequent cache put * @param key key that will be used for subsequent cache put
* @param txTimestamp * @param txTimestamp
*/ */
public void registerPendingPut(Object key, long txTimestamp) { public void registerPendingPut(SessionImplementor session, Object key, long txTimestamp) {
long invalidationTimestamp = this.regionInvalidationTimestamp; long invalidationTimestamp = this.regionInvalidationTimestamp;
if (txTimestamp <= invalidationTimestamp) { if (txTimestamp <= invalidationTimestamp) {
boolean skip; boolean skip;
@ -543,7 +538,7 @@ public class PutFromLoadValidator {
} }
} }
final PendingPut pendingPut = new PendingPut( getLocalLockOwner() ); final PendingPut pendingPut = new PendingPut( session );
final PendingPutMap pendingForKey = new PendingPutMap( pendingPut ); final PendingPutMap pendingForKey = new PendingPutMap( pendingPut );
for (;;) { for (;;) {
@ -586,21 +581,23 @@ public class PutFromLoadValidator {
/** /**
* Calls {@link #beginInvalidatingKey(Object, Object)} with current transaction or thread. * Calls {@link #beginInvalidatingKey(Object, Object)} with current transaction or thread.
*
* @param session
* @param key * @param key
* @return * @return
*/ */
public boolean beginInvalidatingKey(Object key) { public boolean beginInvalidatingKey(SessionImplementor session, Object key) {
return beginInvalidatingKey(key, getLocalLockOwner()); return beginInvalidatingKey(key, session);
} }
/** /**
* Invalidates any {@link #registerPendingPut(Object, long) previously registered pending puts} * Invalidates any {@link #registerPendingPut(SessionImplementor, Object, long) previously registered pending puts}
* and disables further registrations ensuring a subsequent call to {@link #acquirePutFromLoadLock(Object, long)} * and disables further registrations ensuring a subsequent call to {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)}
* will return <code>false</code>. <p> This method will block until any concurrent thread that has * will return <code>false</code>. <p> This method will block until any concurrent thread that has
* {@link #acquirePutFromLoadLock(Object, long) acquired the putFromLoad lock} for the given key * {@link #acquirePutFromLoadLock(SessionImplementor, Object, long) acquired the putFromLoad lock} for the given key
* has released the lock. This allows the caller to be certain the putFromLoad will not execute after this method * has released the lock. This allows the caller to be certain the putFromLoad will not execute after this method
* returns, possibly caching stale data. </p> * returns, possibly caching stale data. </p>
* After this transaction completes, {@link #endInvalidatingKey(Object)} needs to be called } * After this transaction completes, {@link #endInvalidatingKey(SessionImplementor, Object)} needs to be called }
* *
* @param key key identifying data whose pending puts should be invalidated * @param key key identifying data whose pending puts should be invalidated
* *
@ -643,16 +640,18 @@ public class PutFromLoadValidator {
/** /**
* Calls {@link #endInvalidatingKey(Object, Object)} with current transaction or thread. * Calls {@link #endInvalidatingKey(Object, Object)} with current transaction or thread.
*
* @param session
* @param key * @param key
* @return * @return
*/ */
public boolean endInvalidatingKey(Object key) { public boolean endInvalidatingKey(SessionImplementor session, Object key) {
return endInvalidatingKey(key, getLocalLockOwner()); return endInvalidatingKey(key, session);
} }
/** /**
* Called after the transaction completes, allowing caching of entries. It is possible that this method * Called after the transaction completes, allowing caching of entries. It is possible that this method
* is called without previous invocation of {@link #beginInvalidatingKey(Object)}, then it should be a no-op. * is called without previous invocation of {@link #beginInvalidatingKey(SessionImplementor, Object)}, then it should be a no-op.
* *
* @param key * @param key
* @param lockOwner owner of the invalidation - transaction or thread * @param lockOwner owner of the invalidation - transaction or thread
@ -690,31 +689,6 @@ public class PutFromLoadValidator {
} }
public Object registerRemoteInvalidations(Object[] keys) { public Object registerRemoteInvalidations(Object[] keys) {
Transaction tx = null;
try {
if ( transactionManager != null ) {
tx = transactionManager.getTransaction();
}
}
catch (SystemException se) {
throw new CacheException( "Could not obtain transaction", se );
}
if (tx != null) {
if (trace) {
log.tracef("Registering lock owner %s for %s: %s", tx, cache.getName(), Arrays.toString(keys));
}
try {
Synchronization sync = new Synchronization(nonTxPutFromLoadInterceptor, keys);
tx.registerSynchronization(sync);
return sync.uuid;
}
catch (SystemException se) {
throw new CacheException("Cannot register synchronization", se);
}
catch (RollbackException e) {
return null;
}
}
SessionImplementor session = currentSession.get(); SessionImplementor session = currentSession.get();
TransactionCoordinator transactionCoordinator = session == null ? null : session.getTransactionCoordinator(); TransactionCoordinator transactionCoordinator = session == null ? null : session.getTransactionCoordinator();
if (transactionCoordinator != null) { if (transactionCoordinator != null) {
@ -731,20 +705,6 @@ public class PutFromLoadValidator {
// ---------------------------------------------------------------- Private // ---------------------------------------------------------------- Private
private Object getLocalLockOwner() {
Transaction tx = null;
try {
if ( transactionManager != null ) {
tx = transactionManager.getTransaction();
}
}
catch (SystemException se) {
throw new CacheException( "Could not obtain transaction", se );
}
return tx == null ? Thread.currentThread() : tx;
}
/** /**
* Lazy-initialization map for PendingPut. Optimized for the expected usual case where only a * Lazy-initialization map for PendingPut. Optimized for the expected usual case where only a
* single put is pending for a given key. * single put is pending for a given key.
@ -787,7 +747,7 @@ public class PutFromLoadValidator {
sb.append("[]"); sb.append("[]");
} }
else { else {
sb.append(invalidators); sb.append(invalidators.values());
} }
} }
else { else {
@ -968,7 +928,8 @@ public class PutFromLoadValidator {
} }
public String toString() { public String toString() {
return (completed ? "C@" : "R@") + owner; // we can't use SessionImpl.toString() concurrently
return (completed ? "C@" : "R@") + (owner instanceof SessionImplementor ? "Session#" + owner.hashCode() : owner.toString());
} }
public boolean invalidate(long now, long expirationPeriod) { public boolean invalidate(long now, long expirationPeriod) {
@ -995,7 +956,8 @@ public class PutFromLoadValidator {
@Override @Override
public String toString() { public String toString() {
final StringBuilder sb = new StringBuilder("{"); final StringBuilder sb = new StringBuilder("{");
sb.append("Owner=").append(owner); // we can't use SessionImpl.toString() concurrently
sb.append("Owner=").append(owner instanceof SessionImplementor ? "Session#" + owner.hashCode() : owner.toString());
sb.append(", Timestamp=").append(registeredTimestamp); sb.append(", Timestamp=").append(registeredTimestamp);
sb.append('}'); sb.append('}');
return sb.toString(); return sb.toString();

View File

@ -51,19 +51,21 @@ public class TransactionalAccessDelegate {
/** /**
* Attempt to retrieve an object from the cache. * Attempt to retrieve an object from the cache.
* *
*
* @param session
* @param key The key of the item to be retrieved * @param key The key of the item to be retrieved
* @param txTimestamp a timestamp prior to the transaction start time * @param txTimestamp a timestamp prior to the transaction start time
* @return the cached object or <tt>null</tt> * @return the cached object or <tt>null</tt>
* @throws CacheException if the cache retrieval failed * @throws CacheException if the cache retrieval failed
*/ */
@SuppressWarnings("UnusedParameters") @SuppressWarnings("UnusedParameters")
public Object get(Object key, long txTimestamp) throws CacheException { public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
if ( !region.checkValid() ) { if ( !region.checkValid() ) {
return null; return null;
} }
final Object val = cache.get( key ); final Object val = cache.get( key );
if ( val == null ) { if ( val == null ) {
putValidator.registerPendingPut( key, txTimestamp ); putValidator.registerPendingPut(session, key, txTimestamp );
} }
return val; return val;
} }
@ -114,7 +116,7 @@ public class TransactionalAccessDelegate {
return false; return false;
} }
PutFromLoadValidator.Lock lock = putValidator.acquirePutFromLoadLock(key, txTimestamp); PutFromLoadValidator.Lock lock = putValidator.acquirePutFromLoadLock(session, key, txTimestamp);
if ( lock == null) { if ( lock == null) {
if ( TRACE_ENABLED ) { if ( TRACE_ENABLED ) {
log.tracef( "Put from load lock not acquired for key %s", key ); log.tracef( "Put from load lock not acquired for key %s", key );
@ -163,7 +165,7 @@ public class TransactionalAccessDelegate {
// We need to be invalidating even for regular writes; if we were not and the write was followed by eviction // We need to be invalidating even for regular writes; if we were not and the write was followed by eviction
// (or any other invalidation), naked put that was started after the eviction ended but before this insert // (or any other invalidation), naked put that was started after the eviction ended but before this insert
// ended could insert the stale entry into the cache (since the entry was removed by eviction). // ended could insert the stale entry into the cache (since the entry was removed by eviction).
if ( !putValidator.beginInvalidatingKey(key)) { if ( !putValidator.beginInvalidatingKey(session, key)) {
throw new CacheException( throw new CacheException(
"Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName() "Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName()
); );
@ -200,7 +202,7 @@ public class TransactionalAccessDelegate {
// We need to be invalidating even for regular writes; if we were not and the write was followed by eviction // We need to be invalidating even for regular writes; if we were not and the write was followed by eviction
// (or any other invalidation), naked put that was started after the eviction ended but before this update // (or any other invalidation), naked put that was started after the eviction ended but before this update
// ended could insert the stale entry into the cache (since the entry was removed by eviction). // ended could insert the stale entry into the cache (since the entry was removed by eviction).
if ( !putValidator.beginInvalidatingKey(key)) { if ( !putValidator.beginInvalidatingKey(session, key)) {
throw new CacheException( throw new CacheException(
"Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName() "Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName()
); );
@ -223,7 +225,7 @@ public class TransactionalAccessDelegate {
* @throws CacheException if removing the cached item fails * @throws CacheException if removing the cached item fails
*/ */
public void remove(SessionImplementor session, Object key) throws CacheException { public void remove(SessionImplementor session, Object key) throws CacheException {
if ( !putValidator.beginInvalidatingKey(key)) { if ( !putValidator.beginInvalidatingKey(session, key)) {
throw new CacheException( throw new CacheException(
"Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName() "Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName()
); );
@ -294,11 +296,13 @@ public class TransactionalAccessDelegate {
* may not have been successful), after transaction completion. This method * may not have been successful), after transaction completion. This method
* is used by "asynchronous" concurrency strategies. * is used by "asynchronous" concurrency strategies.
* *
*
* @param session
* @param key The item key * @param key The item key
* @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
*/ */
public void unlockItem(Object key) throws CacheException { public void unlockItem(SessionImplementor session, Object key) throws CacheException {
if ( !putValidator.endInvalidatingKey(key) ) { if ( !putValidator.endInvalidatingKey(session, key) ) {
// TODO: localization // TODO: localization
log.warn("Failed to end invalidating pending putFromLoad calls for key " + key + " from region " log.warn("Failed to end invalidating pending putFromLoad calls for key " + key + " from region "
+ region.getName() + "; the key won't be cached until invalidation expires."); + region.getName() + "; the key won't be cached until invalidation expires.");
@ -310,14 +314,16 @@ public class TransactionalAccessDelegate {
* instead of calling release(). * instead of calling release().
* This method is used by "asynchronous" concurrency strategies. * This method is used by "asynchronous" concurrency strategies.
* *
*
* @param session
* @param key The item key * @param key The item key
* @param value The item * @param value The item
* @param version The item's version value * @param version The item's version value
* @return Were the contents of the cache actual changed by this operation? * @return Were the contents of the cache actual changed by this operation?
* @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/ */
public boolean afterInsert(Object key, Object value, Object version) { public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) {
if ( !putValidator.endInvalidatingKey(key) ) { if ( !putValidator.endInvalidatingKey(session, key) ) {
// TODO: localization // TODO: localization
log.warn("Failed to end invalidating pending putFromLoad calls for key " + key + " from region " log.warn("Failed to end invalidating pending putFromLoad calls for key " + key + " from region "
+ region.getName() + "; the key won't be cached until invalidation expires."); + region.getName() + "; the key won't be cached until invalidation expires.");
@ -330,6 +336,8 @@ public class TransactionalAccessDelegate {
* instead of calling release(). This method is used by "asynchronous" * instead of calling release(). This method is used by "asynchronous"
* concurrency strategies. * concurrency strategies.
* *
*
* @param session
* @param key The item key * @param key The item key
* @param value The item * @param value The item
* @param currentVersion The item's current version value * @param currentVersion The item's current version value
@ -338,8 +346,8 @@ public class TransactionalAccessDelegate {
* @return Were the contents of the cache actual changed by this operation? * @return Were the contents of the cache actual changed by this operation?
* @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/ */
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) {
if ( !putValidator.endInvalidatingKey(key) ) { if ( !putValidator.endInvalidatingKey(session, key) ) {
// TODO: localization // TODO: localization
log.warn("Failed to end invalidating pending putFromLoad calls for key " + key + " from region " log.warn("Failed to end invalidating pending putFromLoad calls for key " + key + " from region "
+ region.getName() + "; the key won't be cached until invalidation expires."); + region.getName() + "; the key won't be cached until invalidation expires.");

View File

@ -42,7 +42,7 @@ class TransactionalAccess implements CollectionRegionAccessStrategy {
} }
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException { public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return delegate.get( key, txTimestamp ); return delegate.get( session, key, txTimestamp );
} }
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version) throws CacheException { public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version) throws CacheException {
@ -75,7 +75,7 @@ class TransactionalAccess implements CollectionRegionAccessStrategy {
} }
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException { public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
delegate.unlockItem(key); delegate.unlockItem( session, key);
} }
public void unlockRegion(SoftLock lock) throws CacheException { public void unlockRegion(SoftLock lock) throws CacheException {

View File

@ -42,7 +42,7 @@ class TransactionalAccess implements EntityRegionAccessStrategy {
} }
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException { public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return delegate.get( key, txTimestamp ); return delegate.get( session, key, txTimestamp );
} }
public EntityRegion getRegion() { public EntityRegion getRegion() {
@ -84,19 +84,19 @@ class TransactionalAccess implements EntityRegionAccessStrategy {
} }
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException { public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
delegate.unlockItem(key); delegate.unlockItem( session, key );
} }
public void unlockRegion(SoftLock lock) throws CacheException { public void unlockRegion(SoftLock lock) throws CacheException {
} }
public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) throws CacheException { public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
return delegate.afterInsert(key, value, version); return delegate.afterInsert( session, key, value, version );
} }
public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException { throws CacheException {
return delegate.afterUpdate(key, value, currentVersion, previousVersion, lock); return delegate.afterUpdate( session, key, value, currentVersion, previousVersion, lock );
} }
@Override @Override

View File

@ -53,7 +53,7 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy {
@Override @Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException { public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return delegate.get( key, txTimestamp ); return delegate.get( session, key, txTimestamp );
} }
@Override @Override
@ -89,7 +89,7 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy {
@Override @Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException { public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
delegate.unlockItem(key); delegate.unlockItem( session, key );
} }
@Override @Override
@ -98,12 +98,12 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy {
@Override @Override
public boolean afterInsert(SessionImplementor session, Object key, Object value) throws CacheException { public boolean afterInsert(SessionImplementor session, Object key, Object value) throws CacheException {
return delegate.afterInsert(key, value, null); return delegate.afterInsert( session, key, value, null );
} }
@Override @Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, SoftLock lock) throws CacheException { public boolean afterUpdate(SessionImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
return delegate.afterUpdate(key, value, null, null, lock); return delegate.afterUpdate( session, key, value, null, null, lock );
} }
@Override @Override

View File

@ -7,6 +7,7 @@
package org.hibernate.test.cache.infinispan.access; package org.hibernate.test.cache.infinispan.access;
import javax.transaction.TransactionManager; import javax.transaction.TransactionManager;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -19,6 +20,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.infinispan.access.PutFromLoadValidator;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl; import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl;
import org.hibernate.test.cache.infinispan.util.InfinispanTestingSetup; import org.hibernate.test.cache.infinispan.util.InfinispanTestingSetup;
import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.manager.EmbeddedCacheManager;
@ -38,6 +40,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
/** /**
* Tests of {@link PutFromLoadValidator}. * Tests of {@link PutFromLoadValidator}.
@ -215,14 +218,16 @@ public class PutFromLoadValidatorUnitTestCase {
if (transactional) { if (transactional) {
tm.begin(); tm.begin();
} }
testee.registerPendingPut(KEY1, txTimestamp); SessionImplementor session1 = mock(SessionImplementor.class);
SessionImplementor session2 = mock(SessionImplementor.class);
testee.registerPendingPut(session1, KEY1, txTimestamp);
if (removeRegion) { if (removeRegion) {
testee.beginInvalidatingRegion(); testee.beginInvalidatingRegion();
} else { } else {
testee.beginInvalidatingKey(KEY1); testee.beginInvalidatingKey(session2, KEY1);
} }
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1, txTimestamp); PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session1, KEY1, txTimestamp);
try { try {
assertNull(lock); assertNull(lock);
} }
@ -233,7 +238,7 @@ public class PutFromLoadValidatorUnitTestCase {
if (removeRegion) { if (removeRegion) {
testee.endInvalidatingRegion(); testee.endInvalidatingRegion();
} else { } else {
testee.endInvalidatingKey(KEY1); testee.endInvalidatingKey(session2, KEY1);
} }
} }
} catch (Exception e) { } catch (Exception e) {
@ -271,10 +276,11 @@ public class PutFromLoadValidatorUnitTestCase {
if (transactional) { if (transactional) {
tm.begin(); tm.begin();
} }
testee.registerPendingPut(KEY1, txTimestamp); SessionImplementor session = mock (SessionImplementor.class);
testee.registerPendingPut(session, KEY1, txTimestamp);
registeredLatch.countDown(); registeredLatch.countDown();
registeredLatch.await(5, TimeUnit.SECONDS); registeredLatch.await(5, TimeUnit.SECONDS);
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1, txTimestamp); PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session, KEY1, txTimestamp);
if (lock != null) { if (lock != null) {
try { try {
log.trace("Put from load lock acquired for key = " + KEY1); log.trace("Put from load lock acquired for key = " + KEY1);
@ -344,8 +350,9 @@ public class PutFromLoadValidatorUnitTestCase {
Callable<Boolean> pferCallable = new Callable<Boolean>() { Callable<Boolean> pferCallable = new Callable<Boolean>() {
public Boolean call() throws Exception { public Boolean call() throws Exception {
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
testee.registerPendingPut(KEY1, txTimestamp); SessionImplementor session = mock (SessionImplementor.class);
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1, txTimestamp); testee.registerPendingPut(session, KEY1, txTimestamp);
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session, KEY1, txTimestamp);
if (lock != null) { if (lock != null) {
try { try {
removeLatch.countDown(); removeLatch.countDown();
@ -365,7 +372,8 @@ public class PutFromLoadValidatorUnitTestCase {
public Void call() throws Exception { public Void call() throws Exception {
removeLatch.await(); removeLatch.await();
if (keyOnly) { if (keyOnly) {
testee.beginInvalidatingKey(KEY1); SessionImplementor session = mock (SessionImplementor.class);
testee.beginInvalidatingKey(session, KEY1);
} else { } else {
testee.beginInvalidatingRegion(); testee.beginInvalidatingRegion();
} }
@ -432,9 +440,10 @@ public class PutFromLoadValidatorUnitTestCase {
assertTrue(success); assertTrue(success);
putFromLoadValidator.endInvalidatingRegion();; putFromLoadValidator.endInvalidatingRegion();;
} else { } else {
boolean success = putFromLoadValidator.beginInvalidatingKey(KEY1); SessionImplementor session = mock (SessionImplementor.class);
boolean success = putFromLoadValidator.beginInvalidatingKey(session, KEY1);
assertTrue(success); assertTrue(success);
success = putFromLoadValidator.endInvalidatingKey(KEY1); success = putFromLoadValidator.endInvalidatingKey(session, KEY1);
assertTrue(success); assertTrue(success);
} }
// if we go for the timestamp-based approach, invalidation in the same millisecond // if we go for the timestamp-based approach, invalidation in the same millisecond
@ -455,9 +464,10 @@ public class PutFromLoadValidatorUnitTestCase {
public Void call() throws Exception { public Void call() throws Exception {
try { try {
long txTimestamp = System.currentTimeMillis(); // this should be acquired before UserTransaction.begin() long txTimestamp = System.currentTimeMillis(); // this should be acquired before UserTransaction.begin()
putFromLoadValidator.registerPendingPut(KEY1, txTimestamp); SessionImplementor session = mock (SessionImplementor.class);
putFromLoadValidator.registerPendingPut(session, KEY1, txTimestamp);
PutFromLoadValidator.Lock lock = putFromLoadValidator.acquirePutFromLoadLock(KEY1, txTimestamp); PutFromLoadValidator.Lock lock = putFromLoadValidator.acquirePutFromLoadLock(session, KEY1, txTimestamp);
try { try {
assertNotNull(lock); assertNotNull(lock);
} finally { } finally {
@ -485,7 +495,8 @@ public class PutFromLoadValidatorUnitTestCase {
public Void call() throws Exception { public Void call() throws Exception {
try { try {
long txTimestamp = System.currentTimeMillis(); // this should be acquired before UserTransaction.begin() long txTimestamp = System.currentTimeMillis(); // this should be acquired before UserTransaction.begin()
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1, txTimestamp); SessionImplementor session = mock (SessionImplementor.class);
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session, KEY1, txTimestamp);
try { try {
if (expectSuccess) { if (expectSuccess) {
assertNotNull(lock); assertNotNull(lock);

View File

@ -26,6 +26,7 @@ import org.hibernate.cache.internal.CacheDataDescriptionImpl;
import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase;
import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.NodeEnvironment;
@ -48,6 +49,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
/** /**
* Base class for tests of CollectionRegionAccessStrategy impls. * Base class for tests of CollectionRegionAccessStrategy impls.
@ -71,10 +73,12 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
protected NodeEnvironment localEnvironment; protected NodeEnvironment localEnvironment;
protected CollectionRegionImpl localCollectionRegion; protected CollectionRegionImpl localCollectionRegion;
protected CollectionRegionAccessStrategy localAccessStrategy; protected CollectionRegionAccessStrategy localAccessStrategy;
protected SessionImplementor localSession;
protected NodeEnvironment remoteEnvironment; protected NodeEnvironment remoteEnvironment;
protected CollectionRegionImpl remoteCollectionRegion; protected CollectionRegionImpl remoteCollectionRegion;
protected CollectionRegionAccessStrategy remoteAccessStrategy; protected CollectionRegionAccessStrategy remoteAccessStrategy;
protected SessionImplementor remoteSession;
protected boolean invalidation; protected boolean invalidation;
protected boolean synchronous; protected boolean synchronous;
@ -96,6 +100,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
localCollectionRegion = localEnvironment.getCollectionRegion( REGION_NAME, getCacheDataDescription() ); localCollectionRegion = localEnvironment.getCollectionRegion( REGION_NAME, getCacheDataDescription() );
localAccessStrategy = localCollectionRegion.buildAccessStrategy( getAccessType() ); localAccessStrategy = localCollectionRegion.buildAccessStrategy( getAccessType() );
localSession = mock(SessionImplementor.class);
invalidation = Caches.isInvalidationCache(localCollectionRegion.getCache()); invalidation = Caches.isInvalidationCache(localCollectionRegion.getCache());
synchronous = Caches.isSynchronousCache(localCollectionRegion.getCache()); synchronous = Caches.isSynchronousCache(localCollectionRegion.getCache());
@ -108,6 +113,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
remoteCollectionRegion = remoteEnvironment.getCollectionRegion( REGION_NAME, getCacheDataDescription() ); remoteCollectionRegion = remoteEnvironment.getCollectionRegion( REGION_NAME, getCacheDataDescription() );
remoteAccessStrategy = remoteCollectionRegion.buildAccessStrategy( getAccessType() ); remoteAccessStrategy = remoteCollectionRegion.buildAccessStrategy( getAccessType() );
remoteSession = mock(SessionImplementor.class);
} }
protected abstract String getConfigurationName(); protected abstract String getConfigurationName();
@ -169,7 +175,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
Callable<Void> pferCallable = new Callable<Void>() { Callable<Void> pferCallable = new Callable<Void>() {
public Void call() throws Exception { public Void call() throws Exception {
delegate.putFromLoad(null, "k1", "v1", 0, null ); SessionImplementor session = mock(SessionImplementor.class);
delegate.putFromLoad(session, "k1", "v1", 0, null );
return null; return null;
} }
}; };
@ -180,7 +187,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
Caches.withinTx(localTm, new Callable<Void>() { Caches.withinTx(localTm, new Callable<Void>() {
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
delegate.remove(null, "k1"); SessionImplementor session = mock(SessionImplementor.class);
delegate.remove(session, "k1");
return null; return null;
} }
}); });
@ -219,8 +227,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
PutFromLoadValidator.removeFromCache(cache); PutFromLoadValidator.removeFromCache(cache);
return new PutFromLoadValidator(cache, cm, tm) { return new PutFromLoadValidator(cache, cm, tm) {
@Override @Override
public Lock acquirePutFromLoadLock(Object key, long txTimestamp) { public Lock acquirePutFromLoadLock(SessionImplementor session, Object key, long txTimestamp) {
Lock lock = super.acquirePutFromLoadLock( key, txTimestamp); Lock lock = super.acquirePutFromLoadLock(session, key, txTimestamp);
try { try {
removeLatch.countDown(); removeLatch.countDown();
pferLatch.await( 2, TimeUnit.SECONDS ); pferLatch.await( 2, TimeUnit.SECONDS );
@ -264,15 +272,15 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertEquals( "node1 starts clean", null, localAccessStrategy.get(null, KEY, txTimestamp ) ); assertEquals( "node1 starts clean", null, localAccessStrategy.get(localSession, KEY, txTimestamp ) );
writeLatch1.await(); writeLatch1.await();
if ( useMinimalAPI ) { if ( useMinimalAPI ) {
localAccessStrategy.putFromLoad(null, KEY, VALUE2, txTimestamp, new Integer( 2 ), true ); localAccessStrategy.putFromLoad(localSession, KEY, VALUE2, txTimestamp, new Integer( 2 ), true );
} }
else { else {
localAccessStrategy.putFromLoad(null, KEY, VALUE2, txTimestamp, new Integer( 2 ) ); localAccessStrategy.putFromLoad(localSession, KEY, VALUE2, txTimestamp, new Integer( 2 ) );
} }
BatchModeTransactionManager.getInstance().commit(); BatchModeTransactionManager.getInstance().commit();
@ -302,7 +310,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertNull( "node2 starts clean", remoteAccessStrategy.get(null, KEY, txTimestamp ) ); assertNull( "node2 starts clean", remoteAccessStrategy.get(remoteSession, KEY, txTimestamp ) );
// Let node1 write // Let node1 write
writeLatch1.countDown(); writeLatch1.countDown();
@ -313,10 +321,10 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
sleep( 200 ); sleep( 200 );
if ( useMinimalAPI ) { if ( useMinimalAPI ) {
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer( 1 ), true ); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer( 1 ), true );
} }
else { else {
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer( 1 ) ); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer( 1 ) );
} }
BatchModeTransactionManager.getInstance().commit(); BatchModeTransactionManager.getInstance().commit();
@ -376,8 +384,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
expected2 = VALUE2; expected2 = VALUE2;
} }
assertEquals( msg1, expected1, localAccessStrategy.get(null, KEY, txTimestamp ) ); assertEquals( msg1, expected1, localAccessStrategy.get(localSession, KEY, txTimestamp ) );
assertEquals( msg2, expected2, remoteAccessStrategy.get(null, KEY, txTimestamp ) ); assertEquals( msg2, expected2, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp ) );
} }
@Test @Test
@ -404,13 +412,13 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ ); final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ );
assertNull( "local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertNull( "local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
assertNull( "remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertNull( "remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) ); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
assertEquals( VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) ); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
assertEquals( VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
// Wait for async propagation // Wait for async propagation
sleep( 250 ); sleep( 250 );
@ -421,14 +429,14 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
if (evict) if (evict)
localAccessStrategy.evict(KEY); localAccessStrategy.evict(KEY);
else else
localAccessStrategy.remove(null, KEY); localAccessStrategy.remove(localSession, KEY);
return null; return null;
} }
}); });
assertEquals( null, localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( null, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
assertEquals( null, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( null, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
} }
private void evictOrRemoveAllTest(final boolean evict) throws Exception { private void evictOrRemoveAllTest(final boolean evict) throws Exception {
@ -439,13 +447,13 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
assertEquals( 0, remoteCollectionRegion.getCache().size() ); assertEquals( 0, remoteCollectionRegion.getCache().size() );
assertNull( "local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertNull( "local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
assertNull( "remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertNull( "remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) ); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
assertEquals( VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) ); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
assertEquals( VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
// Wait for async propagation // Wait for async propagation
sleep( 250 ); sleep( 250 );
@ -462,13 +470,13 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
}); });
// This should re-establish the region root node // This should re-establish the region root node
assertNull( localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertNull( localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
assertEquals( 0, localCollectionRegion.getCache().size() ); assertEquals( 0, localCollectionRegion.getCache().size() );
// Re-establishing the region root on the local node doesn't // Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish // propagate it to other nodes. Do a get on the remote node to re-establish
assertEquals( null, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( null, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
assertEquals( 0, remoteCollectionRegion.getCache().size() ); assertEquals( 0, remoteCollectionRegion.getCache().size() );
@ -476,8 +484,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
sleep( 250 ); sleep( 250 );
// Test whether the get above messes up the optimistic version // Test whether the get above messes up the optimistic version
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) ); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
assertEquals( VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
assertEquals( 1, remoteCollectionRegion.getCache().size() ); assertEquals( 1, remoteCollectionRegion.getCache().size() );
@ -486,11 +494,11 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
assertEquals( assertEquals(
"local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get( "local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(
null, KEY, System localSession, KEY, System
.currentTimeMillis() .currentTimeMillis()
) )
); );
assertEquals( "remote is correct", VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) ); assertEquals( "remote is correct", VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
} }
private void rollback() { private void rollback() {

View File

@ -20,6 +20,7 @@ import org.hibernate.cache.internal.CacheDataDescriptionImpl;
import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase;
import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.NodeEnvironment;
@ -38,6 +39,7 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
/** /**
* Base class for tests of EntityRegionAccessStrategy impls. * Base class for tests of EntityRegionAccessStrategy impls.
@ -62,10 +64,12 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
protected NodeEnvironment localEnvironment; protected NodeEnvironment localEnvironment;
protected EntityRegionImpl localEntityRegion; protected EntityRegionImpl localEntityRegion;
protected EntityRegionAccessStrategy localAccessStrategy; protected EntityRegionAccessStrategy localAccessStrategy;
protected SessionImplementor localSession;
protected NodeEnvironment remoteEnvironment; protected NodeEnvironment remoteEnvironment;
protected EntityRegionImpl remoteEntityRegion; protected EntityRegionImpl remoteEntityRegion;
protected EntityRegionAccessStrategy remoteAccessStrategy; protected EntityRegionAccessStrategy remoteAccessStrategy;
protected SessionImplementor remoteSession;
protected boolean invalidation; protected boolean invalidation;
protected boolean synchronous; protected boolean synchronous;
@ -85,6 +89,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
localEntityRegion = localEnvironment.getEntityRegion(REGION_NAME, getCacheDataDescription()); localEntityRegion = localEnvironment.getEntityRegion(REGION_NAME, getCacheDataDescription());
localAccessStrategy = localEntityRegion.buildAccessStrategy(getAccessType()); localAccessStrategy = localEntityRegion.buildAccessStrategy(getAccessType());
localSession = mock(SessionImplementor.class);
remoteSession = mock(SessionImplementor.class);
invalidation = Caches.isInvalidationCache(localEntityRegion.getCache()); invalidation = Caches.isInvalidationCache(localEntityRegion.getCache());
synchronous = Caches.isSynchronousCache(localEntityRegion.getCache()); synchronous = Caches.isSynchronousCache(localEntityRegion.getCache());
@ -211,17 +218,17 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertNull("node1 starts clean", localAccessStrategy.get(null, KEY, txTimestamp)); assertNull("node1 starts clean", localAccessStrategy.get(localSession, KEY, txTimestamp));
writeLatch1.await(); writeLatch1.await();
if (useMinimalAPI) { if (useMinimalAPI) {
localAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer(1), true); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, txTimestamp, new Integer(1), true);
} else { } else {
localAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer(1)); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, txTimestamp, new Integer(1));
} }
localAccessStrategy.update(null, KEY, VALUE2, new Integer(2), new Integer(1)); localAccessStrategy.update(localSession, KEY, VALUE2, new Integer(2), new Integer(1));
BatchModeTransactionManager.getInstance().commit(); BatchModeTransactionManager.getInstance().commit();
} catch (Exception e) { } catch (Exception e) {
@ -248,7 +255,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertNull("node1 starts clean", remoteAccessStrategy.get(null, KEY, txTimestamp)); assertNull("node1 starts clean", remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
// Let node1 write // Let node1 write
writeLatch1.countDown(); writeLatch1.countDown();
@ -256,9 +263,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
writeLatch2.await(); writeLatch2.await();
if (useMinimalAPI) { if (useMinimalAPI) {
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer(1), true); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer(1), true);
} else { } else {
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer(1)); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer(1));
} }
BatchModeTransactionManager.getInstance().commit(); BatchModeTransactionManager.getInstance().commit();
@ -286,14 +293,14 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertThreadsRanCleanly(); assertThreadsRanCleanly();
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(localSession, KEY, txTimestamp));
if (isUsingInvalidation()) { if (isUsingInvalidation()) {
// invalidation command invalidates pending put // invalidation command invalidates pending put
assertEquals("Expected node2 value", null, remoteAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Expected node2 value", null, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
} else { } else {
// The node1 update is replicated, preventing the node2 PFER // The node1 update is replicated, preventing the node2 PFER
assertEquals("Correct node2 value", VALUE2, remoteAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct node2 value", VALUE2, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
} }
} }
@ -315,9 +322,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertNull("Correct initial value", localAccessStrategy.get(null, KEY, txTimestamp)); assertNull("Correct initial value", localAccessStrategy.get(localSession, KEY, txTimestamp));
localAccessStrategy.insert(null, KEY, VALUE1, new Integer(1)); localAccessStrategy.insert(localSession, KEY, VALUE1, new Integer(1));
readLatch.countDown(); readLatch.countDown();
commitLatch.await(); commitLatch.await();
@ -351,7 +358,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertEquals( assertEquals(
"Correct initial value", expected, localAccessStrategy.get( "Correct initial value", expected, localAccessStrategy.get(
null, KEY, localSession, KEY,
txTimestamp txTimestamp
) )
); );
@ -381,9 +388,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertThreadsRanCleanly(); assertThreadsRanCleanly();
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE1, localAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct node1 value", VALUE1, localAccessStrategy.get(localSession, KEY, txTimestamp));
Object expected = isUsingInvalidation() ? null : VALUE1; Object expected = isUsingInvalidation() ? null : VALUE1;
assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
} }
@Test @Test
@ -392,8 +399,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
// Set up initial state // Set up initial state
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
// Let the async put propagate // Let the async put propagate
sleep(250); sleep(250);
@ -411,9 +418,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
log.debug("Transaction began, get initial value"); log.debug("Transaction began, get initial value");
assertEquals("Correct initial value", VALUE1, localAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct initial value", VALUE1, localAccessStrategy.get(localSession, KEY, txTimestamp));
log.debug("Now update value"); log.debug("Now update value");
localAccessStrategy.update(null, KEY, VALUE2, new Integer(2), new Integer(1)); localAccessStrategy.update(localSession, KEY, VALUE2, new Integer(2), new Integer(1));
log.debug("Notify the read latch"); log.debug("Notify the read latch");
readLatch.countDown(); readLatch.countDown();
readerUnlocked = true; readerUnlocked = true;
@ -450,7 +457,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
// This won't block w/ mvc and will read the old value // This won't block w/ mvc and will read the old value
Object expected = VALUE1; Object expected = VALUE1;
assertEquals("Correct value", expected, localAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct value", expected, localAccessStrategy.get(localSession, KEY, txTimestamp));
BatchModeTransactionManager.getInstance().commit(); BatchModeTransactionManager.getInstance().commit();
} catch (Exception e) { } catch (Exception e) {
@ -479,9 +486,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertThreadsRanCleanly(); assertThreadsRanCleanly();
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(localSession, KEY, txTimestamp));
Object expected = isUsingInvalidation() ? null : VALUE2; Object expected = isUsingInvalidation() ? null : VALUE2;
assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
} }
@Test @Test
@ -509,13 +516,13 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertEquals(0, localEntityRegion.getCache().size()); assertEquals(0, localEntityRegion.getCache().size());
assertEquals(0, remoteEntityRegion.getCache().size()); assertEquals(0, remoteEntityRegion.getCache().size());
assertNull("local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertNull("local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
assertNull("remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
Caches.withinTx(localEntityRegion.getTransactionManager(), new Callable<Void>() { Caches.withinTx(localEntityRegion.getTransactionManager(), new Callable<Void>() {
@Override @Override
@ -523,13 +530,13 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
if (evict) if (evict)
localAccessStrategy.evict(KEY); localAccessStrategy.evict(KEY);
else else
localAccessStrategy.remove(null, KEY); localAccessStrategy.remove(localSession, KEY);
return null; return null;
} }
}); });
assertEquals(null, localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(null, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
assertEquals(0, localEntityRegion.getCache().size()); assertEquals(0, localEntityRegion.getCache().size());
assertEquals(null, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(null, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
assertEquals(0, remoteEntityRegion.getCache().size()); assertEquals(0, remoteEntityRegion.getCache().size());
} }
@ -537,17 +544,17 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
assertEquals(0, localEntityRegion.getCache().size()); assertEquals(0, localEntityRegion.getCache().size());
assertEquals(0, remoteEntityRegion.getCache().size()); assertEquals(0, remoteEntityRegion.getCache().size());
assertNull("local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertNull("local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
assertNull("remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
// Wait for async propagation // Wait for async propagation
sleep(250); sleep(250);
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
// Wait for async propagation // Wait for async propagation
sleep(250); sleep(250);
@ -566,20 +573,20 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
}); });
// This should re-establish the region root node in the optimistic case // This should re-establish the region root node in the optimistic case
assertNull(localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertNull(localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
assertEquals(0, localEntityRegion.getCache().size()); assertEquals(0, localEntityRegion.getCache().size());
// Re-establishing the region root on the local node doesn't // Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish // propagate it to other nodes. Do a get on the remote node to re-establish
assertNull(remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertNull(remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
assertEquals(0, remoteEntityRegion.getCache().size()); assertEquals(0, remoteEntityRegion.getCache().size());
// Wait for async propagation of EndInvalidationCommand before executing naked put // Wait for async propagation of EndInvalidationCommand before executing naked put
sleep(250); sleep(250);
// Test whether the get above messes up the optimistic version // Test whether the get above messes up the optimistic version
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
assertEquals(1, remoteEntityRegion.getCache().size()); assertEquals(1, remoteEntityRegion.getCache().size());
// Wait for async propagation // Wait for async propagation
@ -587,11 +594,11 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertEquals( assertEquals(
"local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy "local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy
.get(null, KEY, System.currentTimeMillis()) .get(localSession, KEY, System.currentTimeMillis())
); );
assertEquals( assertEquals(
"remote is correct", VALUE1, remoteAccessStrategy.get( "remote is correct", VALUE1, remoteAccessStrategy.get(
null, KEY, System remoteSession, KEY, System
.currentTimeMillis() .currentTimeMillis()
) )
); );

View File

@ -45,26 +45,26 @@ public abstract class AbstractReadOnlyAccessTestCase extends AbstractEntityRegio
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertNull(localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertNull(localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
if (minimal) if (minimal)
localAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, 1, true); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, txTimestamp, 1, true);
else else
localAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, 1); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, txTimestamp, 1);
sleep(250); sleep(250);
Object expected = isUsingInvalidation() ? null : VALUE1; Object expected = isUsingInvalidation() ? null : VALUE1;
assertEquals(expected, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(expected, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
BatchModeTransactionManager.getInstance().commit(); BatchModeTransactionManager.getInstance().commit();
assertEquals(VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
assertEquals(expected, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis())); assertEquals(expected, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
} }
@Test(expected = UnsupportedOperationException.class) @Test(expected = UnsupportedOperationException.class)
@Override @Override
public void testUpdate() throws Exception { public void testUpdate() throws Exception {
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
localAccessStrategy.update(null, KEY, VALUE2, 2, 1); localAccessStrategy.update(localSession, KEY, VALUE2, 2, 1);
} }
} }

View File

@ -36,7 +36,7 @@ public abstract class AbstractTransactionalAccessTestCase extends AbstractEntity
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
final CountDownLatch pferLatch = new CountDownLatch(1); final CountDownLatch pferLatch = new CountDownLatch(1);
final CountDownLatch pferCompletionLatch = new CountDownLatch(1); final CountDownLatch pferCompletionLatch = new CountDownLatch(1);
@ -52,9 +52,9 @@ public abstract class AbstractTransactionalAccessTestCase extends AbstractEntity
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertEquals("Correct initial value", VALUE1, localAccessStrategy.get(null, KEY, txTimestamp)); assertEquals("Correct initial value", VALUE1, localAccessStrategy.get(localSession, KEY, txTimestamp));
localAccessStrategy.update(null, KEY, VALUE2, new Integer(2), new Integer(1)); localAccessStrategy.update(localSession, KEY, VALUE2, new Integer(2), new Integer(1));
pferLatch.countDown(); pferLatch.countDown();
commitLatch.await(); commitLatch.await();