HHH-9868, HHH-9881 Replaced access to TransactionManager with Session
This commit is contained in:
parent
1f24fa6354
commit
984125e87e
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.");
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue