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_server )
|
||||
testCompile( libraries.rhq )
|
||||
testCompile( libraries.mockito )
|
||||
testCompile ('mysql:mysql-connector-java:5.1.17')
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.cache.infinispan.access;
|
||||
|
||||
import javax.transaction.RollbackException;
|
||||
import javax.transaction.Status;
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.Transaction;
|
||||
|
@ -24,7 +23,6 @@ import java.util.concurrent.ConcurrentMap;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
|
||||
import org.hibernate.cache.infinispan.util.CacheCommandInitializer;
|
||||
import org.hibernate.cache.spi.RegionFactory;
|
||||
|
@ -53,9 +51,9 @@ import org.infinispan.util.logging.LogFactory;
|
|||
* not find data is:
|
||||
* <p/>
|
||||
* <ol>
|
||||
* <li> Call {@link #registerPendingPut(Object, long)}</li>
|
||||
* <li> Call {@link #registerPendingPut(SessionImplementor, Object, long)}</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;
|
||||
* only if above returns instance of <code>AcquiredLock</code>, put data in the cache and...</li>
|
||||
* <li> then call {@link #releasePutFromLoadLock(Object, Lock)}</li>
|
||||
|
@ -68,18 +66,18 @@ import org.infinispan.util.logging.LogFactory;
|
|||
* call
|
||||
* <p/>
|
||||
* <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()}
|
||||
* (for a general invalidation all pending puts)</li>
|
||||
* </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.
|
||||
* </p>
|
||||
* <p/>
|
||||
* <p>
|
||||
* This class also supports the concept of "naked puts", which are calls to
|
||||
* {@link #acquirePutFromLoadLock(Object, long)} without a preceding {@link #registerPendingPut(Object, long)}.
|
||||
* Besides not acquiring lock in {@link #registerPendingPut(Object, long)} this can happen when collection
|
||||
* {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)} without a preceding {@link #registerPendingPut(SessionImplementor, Object, long)}.
|
||||
* 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
|
||||
* 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()}
|
||||
|
@ -247,20 +245,15 @@ public class PutFromLoadValidator {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetCurrentSession() {
|
||||
if (transactionManager == null) {
|
||||
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 {
|
||||
private Lock() {}
|
||||
|
@ -274,13 +267,14 @@ public class PutFromLoadValidator {
|
|||
* should always be matched with a call to {@link #releasePutFromLoadLock(Object, Lock)}.
|
||||
* </p>
|
||||
*
|
||||
* @param session
|
||||
* @param key the key
|
||||
*
|
||||
* @param txTimestamp
|
||||
* @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
|
||||
*/
|
||||
public Lock acquirePutFromLoadLock(Object key, long txTimestamp) {
|
||||
public Lock acquirePutFromLoadLock(SessionImplementor session, Object key, long txTimestamp) {
|
||||
if (trace) {
|
||||
log.tracef("acquirePutFromLoadLock(%s#%s, %d)", cache.getName(), key, txTimestamp);
|
||||
}
|
||||
|
@ -305,7 +299,7 @@ public class PutFromLoadValidator {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
final PendingPut toCancel = pending.remove(getLocalLockOwner());
|
||||
final PendingPut toCancel = pending.remove(session);
|
||||
if (toCancel != null) {
|
||||
valid = !toCancel.completed;
|
||||
toCancel.completed = true;
|
||||
|
@ -359,7 +353,7 @@ public class PutFromLoadValidator {
|
|||
}
|
||||
}
|
||||
|
||||
PendingPut pendingPut = new PendingPut(getLocalLockOwner());
|
||||
PendingPut pendingPut = new PendingPut(session);
|
||||
pending = new PendingPutMap(pendingPut);
|
||||
PendingPutMap existing = pendingPuts.putIfAbsent(key, pending);
|
||||
if (existing != null) {
|
||||
|
@ -388,7 +382,7 @@ public class PutFromLoadValidator {
|
|||
|
||||
/**
|
||||
* Releases the lock previously obtained by a call to
|
||||
* {@link #acquirePutFromLoadLock(Object, long)}.
|
||||
* {@link #acquirePutFromLoadLock(SessionImplementor, Object, long)}.
|
||||
*
|
||||
* @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
|
||||
* {@link #acquirePutFromLoadLock(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
|
||||
* Invalidates all {@link #registerPendingPut(SessionImplementor, Object, long) previously registered pending puts} 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 {@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,
|
||||
* 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
|
||||
* #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
|
||||
* 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
|
||||
* notifications.
|
||||
*
|
||||
* @param session
|
||||
* @param key key that will be used for subsequent cache put
|
||||
* @param txTimestamp
|
||||
*/
|
||||
public void registerPendingPut(Object key, long txTimestamp) {
|
||||
public void registerPendingPut(SessionImplementor session, Object key, long txTimestamp) {
|
||||
long invalidationTimestamp = this.regionInvalidationTimestamp;
|
||||
if (txTimestamp <= invalidationTimestamp) {
|
||||
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 );
|
||||
|
||||
for (;;) {
|
||||
|
@ -586,21 +581,23 @@ public class PutFromLoadValidator {
|
|||
|
||||
/**
|
||||
* Calls {@link #beginInvalidatingKey(Object, Object)} with current transaction or thread.
|
||||
*
|
||||
* @param session
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public boolean beginInvalidatingKey(Object key) {
|
||||
return beginInvalidatingKey(key, getLocalLockOwner());
|
||||
public boolean beginInvalidatingKey(SessionImplementor session, Object key) {
|
||||
return beginInvalidatingKey(key, session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates any {@link #registerPendingPut(Object, long) previously registered pending puts}
|
||||
* and disables further registrations ensuring a subsequent call to {@link #acquirePutFromLoadLock(Object, long)}
|
||||
* Invalidates any {@link #registerPendingPut(SessionImplementor, Object, long) previously registered pending puts}
|
||||
* 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
|
||||
* {@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
|
||||
* 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
|
||||
*
|
||||
|
@ -643,16 +640,18 @@ public class PutFromLoadValidator {
|
|||
|
||||
/**
|
||||
* Calls {@link #endInvalidatingKey(Object, Object)} with current transaction or thread.
|
||||
*
|
||||
* @param session
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public boolean endInvalidatingKey(Object key) {
|
||||
return endInvalidatingKey(key, getLocalLockOwner());
|
||||
public boolean endInvalidatingKey(SessionImplementor session, Object key) {
|
||||
return endInvalidatingKey(key, session);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 lockOwner owner of the invalidation - transaction or thread
|
||||
|
@ -690,31 +689,6 @@ public class PutFromLoadValidator {
|
|||
}
|
||||
|
||||
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();
|
||||
TransactionCoordinator transactionCoordinator = session == null ? null : session.getTransactionCoordinator();
|
||||
if (transactionCoordinator != null) {
|
||||
|
@ -731,20 +705,6 @@ public class PutFromLoadValidator {
|
|||
|
||||
// ---------------------------------------------------------------- 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
|
||||
* single put is pending for a given key.
|
||||
|
@ -787,7 +747,7 @@ public class PutFromLoadValidator {
|
|||
sb.append("[]");
|
||||
}
|
||||
else {
|
||||
sb.append(invalidators);
|
||||
sb.append(invalidators.values());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -968,7 +928,8 @@ public class PutFromLoadValidator {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -995,7 +956,8 @@ public class PutFromLoadValidator {
|
|||
@Override
|
||||
public String toString() {
|
||||
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('}');
|
||||
return sb.toString();
|
||||
|
|
|
@ -51,19 +51,21 @@ public class TransactionalAccessDelegate {
|
|||
/**
|
||||
* Attempt to retrieve an object from the cache.
|
||||
*
|
||||
*
|
||||
* @param session
|
||||
* @param key The key of the item to be retrieved
|
||||
* @param txTimestamp a timestamp prior to the transaction start time
|
||||
* @return the cached object or <tt>null</tt>
|
||||
* @throws CacheException if the cache retrieval failed
|
||||
*/
|
||||
@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() ) {
|
||||
return null;
|
||||
}
|
||||
final Object val = cache.get( key );
|
||||
if ( val == null ) {
|
||||
putValidator.registerPendingPut( key, txTimestamp );
|
||||
putValidator.registerPendingPut(session, key, txTimestamp );
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
@ -114,7 +116,7 @@ public class TransactionalAccessDelegate {
|
|||
return false;
|
||||
}
|
||||
|
||||
PutFromLoadValidator.Lock lock = putValidator.acquirePutFromLoadLock(key, txTimestamp);
|
||||
PutFromLoadValidator.Lock lock = putValidator.acquirePutFromLoadLock(session, key, txTimestamp);
|
||||
if ( lock == null) {
|
||||
if ( TRACE_ENABLED ) {
|
||||
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
|
||||
// (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).
|
||||
if ( !putValidator.beginInvalidatingKey(key)) {
|
||||
if ( !putValidator.beginInvalidatingKey(session, key)) {
|
||||
throw new CacheException(
|
||||
"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
|
||||
// (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).
|
||||
if ( !putValidator.beginInvalidatingKey(key)) {
|
||||
if ( !putValidator.beginInvalidatingKey(session, key)) {
|
||||
throw new CacheException(
|
||||
"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
|
||||
*/
|
||||
public void remove(SessionImplementor session, Object key) throws CacheException {
|
||||
if ( !putValidator.beginInvalidatingKey(key)) {
|
||||
if ( !putValidator.beginInvalidatingKey(session, key)) {
|
||||
throw new CacheException(
|
||||
"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
|
||||
* is used by "asynchronous" concurrency strategies.
|
||||
*
|
||||
*
|
||||
* @param session
|
||||
* @param key The item key
|
||||
* @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
|
||||
*/
|
||||
public void unlockItem(Object key) throws CacheException {
|
||||
if ( !putValidator.endInvalidatingKey(key) ) {
|
||||
public void unlockItem(SessionImplementor session, Object key) throws CacheException {
|
||||
if ( !putValidator.endInvalidatingKey(session, key) ) {
|
||||
// TODO: localization
|
||||
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.");
|
||||
|
@ -310,14 +314,16 @@ public class TransactionalAccessDelegate {
|
|||
* instead of calling release().
|
||||
* This method is used by "asynchronous" concurrency strategies.
|
||||
*
|
||||
*
|
||||
* @param session
|
||||
* @param key The item key
|
||||
* @param value The item
|
||||
* @param version The item's version value
|
||||
* @return Were the contents of the cache actual changed by this operation?
|
||||
* @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
|
||||
*/
|
||||
public boolean afterInsert(Object key, Object value, Object version) {
|
||||
if ( !putValidator.endInvalidatingKey(key) ) {
|
||||
public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) {
|
||||
if ( !putValidator.endInvalidatingKey(session, key) ) {
|
||||
// TODO: localization
|
||||
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.");
|
||||
|
@ -330,6 +336,8 @@ public class TransactionalAccessDelegate {
|
|||
* instead of calling release(). This method is used by "asynchronous"
|
||||
* concurrency strategies.
|
||||
*
|
||||
*
|
||||
* @param session
|
||||
* @param key The item key
|
||||
* @param value The item
|
||||
* @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?
|
||||
* @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
|
||||
*/
|
||||
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) {
|
||||
if ( !putValidator.endInvalidatingKey(key) ) {
|
||||
public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) {
|
||||
if ( !putValidator.endInvalidatingKey(session, key) ) {
|
||||
// TODO: localization
|
||||
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.");
|
||||
|
|
|
@ -42,7 +42,7 @@ class TransactionalAccess implements CollectionRegionAccessStrategy {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -75,7 +75,7 @@ class TransactionalAccess implements CollectionRegionAccessStrategy {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -42,7 +42,7 @@ class TransactionalAccess implements EntityRegionAccessStrategy {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
@ -84,19 +84,19 @@ class TransactionalAccess implements EntityRegionAccessStrategy {
|
|||
}
|
||||
|
||||
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 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)
|
||||
throws CacheException {
|
||||
return delegate.afterUpdate(key, value, currentVersion, previousVersion, lock);
|
||||
return delegate.afterUpdate( session, key, value, currentVersion, previousVersion, lock );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,7 +53,7 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy {
|
|||
|
||||
@Override
|
||||
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
|
||||
return delegate.get( key, txTimestamp );
|
||||
return delegate.get( session, key, txTimestamp );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,7 +89,7 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy {
|
|||
|
||||
@Override
|
||||
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
|
||||
delegate.unlockItem(key);
|
||||
delegate.unlockItem( session, key );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,12 +98,12 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy {
|
|||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.test.cache.infinispan.access;
|
||||
|
||||
import javax.transaction.TransactionManager;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
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.access.PutFromLoadValidator;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl;
|
||||
import org.hibernate.test.cache.infinispan.util.InfinispanTestingSetup;
|
||||
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.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests of {@link PutFromLoadValidator}.
|
||||
|
@ -215,14 +218,16 @@ public class PutFromLoadValidatorUnitTestCase {
|
|||
if (transactional) {
|
||||
tm.begin();
|
||||
}
|
||||
testee.registerPendingPut(KEY1, txTimestamp);
|
||||
SessionImplementor session1 = mock(SessionImplementor.class);
|
||||
SessionImplementor session2 = mock(SessionImplementor.class);
|
||||
testee.registerPendingPut(session1, KEY1, txTimestamp);
|
||||
if (removeRegion) {
|
||||
testee.beginInvalidatingRegion();
|
||||
} else {
|
||||
testee.beginInvalidatingKey(KEY1);
|
||||
testee.beginInvalidatingKey(session2, KEY1);
|
||||
}
|
||||
|
||||
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1, txTimestamp);
|
||||
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session1, KEY1, txTimestamp);
|
||||
try {
|
||||
assertNull(lock);
|
||||
}
|
||||
|
@ -233,7 +238,7 @@ public class PutFromLoadValidatorUnitTestCase {
|
|||
if (removeRegion) {
|
||||
testee.endInvalidatingRegion();
|
||||
} else {
|
||||
testee.endInvalidatingKey(KEY1);
|
||||
testee.endInvalidatingKey(session2, KEY1);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -271,10 +276,11 @@ public class PutFromLoadValidatorUnitTestCase {
|
|||
if (transactional) {
|
||||
tm.begin();
|
||||
}
|
||||
testee.registerPendingPut(KEY1, txTimestamp);
|
||||
SessionImplementor session = mock (SessionImplementor.class);
|
||||
testee.registerPendingPut(session, KEY1, txTimestamp);
|
||||
registeredLatch.countDown();
|
||||
registeredLatch.await(5, TimeUnit.SECONDS);
|
||||
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1, txTimestamp);
|
||||
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session, KEY1, txTimestamp);
|
||||
if (lock != null) {
|
||||
try {
|
||||
log.trace("Put from load lock acquired for key = " + KEY1);
|
||||
|
@ -344,8 +350,9 @@ public class PutFromLoadValidatorUnitTestCase {
|
|||
Callable<Boolean> pferCallable = new Callable<Boolean>() {
|
||||
public Boolean call() throws Exception {
|
||||
long txTimestamp = System.currentTimeMillis();
|
||||
testee.registerPendingPut(KEY1, txTimestamp);
|
||||
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1, txTimestamp);
|
||||
SessionImplementor session = mock (SessionImplementor.class);
|
||||
testee.registerPendingPut(session, KEY1, txTimestamp);
|
||||
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session, KEY1, txTimestamp);
|
||||
if (lock != null) {
|
||||
try {
|
||||
removeLatch.countDown();
|
||||
|
@ -365,7 +372,8 @@ public class PutFromLoadValidatorUnitTestCase {
|
|||
public Void call() throws Exception {
|
||||
removeLatch.await();
|
||||
if (keyOnly) {
|
||||
testee.beginInvalidatingKey(KEY1);
|
||||
SessionImplementor session = mock (SessionImplementor.class);
|
||||
testee.beginInvalidatingKey(session, KEY1);
|
||||
} else {
|
||||
testee.beginInvalidatingRegion();
|
||||
}
|
||||
|
@ -432,9 +440,10 @@ public class PutFromLoadValidatorUnitTestCase {
|
|||
assertTrue(success);
|
||||
putFromLoadValidator.endInvalidatingRegion();;
|
||||
} else {
|
||||
boolean success = putFromLoadValidator.beginInvalidatingKey(KEY1);
|
||||
SessionImplementor session = mock (SessionImplementor.class);
|
||||
boolean success = putFromLoadValidator.beginInvalidatingKey(session, KEY1);
|
||||
assertTrue(success);
|
||||
success = putFromLoadValidator.endInvalidatingKey(KEY1);
|
||||
success = putFromLoadValidator.endInvalidatingKey(session, KEY1);
|
||||
assertTrue(success);
|
||||
}
|
||||
// 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 {
|
||||
try {
|
||||
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 {
|
||||
assertNotNull(lock);
|
||||
} finally {
|
||||
|
@ -485,7 +495,8 @@ public class PutFromLoadValidatorUnitTestCase {
|
|||
public Void call() throws Exception {
|
||||
try {
|
||||
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 {
|
||||
if (expectSuccess) {
|
||||
assertNotNull(lock);
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.hibernate.cache.internal.CacheDataDescriptionImpl;
|
|||
import org.hibernate.cache.spi.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.internal.util.compare.ComparableComparator;
|
||||
import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase;
|
||||
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.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Base class for tests of CollectionRegionAccessStrategy impls.
|
||||
|
@ -71,10 +73,12 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
protected NodeEnvironment localEnvironment;
|
||||
protected CollectionRegionImpl localCollectionRegion;
|
||||
protected CollectionRegionAccessStrategy localAccessStrategy;
|
||||
protected SessionImplementor localSession;
|
||||
|
||||
protected NodeEnvironment remoteEnvironment;
|
||||
protected CollectionRegionImpl remoteCollectionRegion;
|
||||
protected CollectionRegionAccessStrategy remoteAccessStrategy;
|
||||
protected SessionImplementor remoteSession;
|
||||
|
||||
protected boolean invalidation;
|
||||
protected boolean synchronous;
|
||||
|
@ -96,6 +100,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
|
||||
localCollectionRegion = localEnvironment.getCollectionRegion( REGION_NAME, getCacheDataDescription() );
|
||||
localAccessStrategy = localCollectionRegion.buildAccessStrategy( getAccessType() );
|
||||
localSession = mock(SessionImplementor.class);
|
||||
|
||||
invalidation = Caches.isInvalidationCache(localCollectionRegion.getCache());
|
||||
synchronous = Caches.isSynchronousCache(localCollectionRegion.getCache());
|
||||
|
@ -108,6 +113,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
|
||||
remoteCollectionRegion = remoteEnvironment.getCollectionRegion( REGION_NAME, getCacheDataDescription() );
|
||||
remoteAccessStrategy = remoteCollectionRegion.buildAccessStrategy( getAccessType() );
|
||||
remoteSession = mock(SessionImplementor.class);
|
||||
}
|
||||
|
||||
protected abstract String getConfigurationName();
|
||||
|
@ -169,7 +175,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
|
||||
Callable<Void> pferCallable = new Callable<Void>() {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
@ -180,7 +187,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
Caches.withinTx(localTm, new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
delegate.remove(null, "k1");
|
||||
SessionImplementor session = mock(SessionImplementor.class);
|
||||
delegate.remove(session, "k1");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
@ -219,8 +227,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
PutFromLoadValidator.removeFromCache(cache);
|
||||
return new PutFromLoadValidator(cache, cm, tm) {
|
||||
@Override
|
||||
public Lock acquirePutFromLoadLock(Object key, long txTimestamp) {
|
||||
Lock lock = super.acquirePutFromLoadLock( key, txTimestamp);
|
||||
public Lock acquirePutFromLoadLock(SessionImplementor session, Object key, long txTimestamp) {
|
||||
Lock lock = super.acquirePutFromLoadLock(session, key, txTimestamp);
|
||||
try {
|
||||
removeLatch.countDown();
|
||||
pferLatch.await( 2, TimeUnit.SECONDS );
|
||||
|
@ -264,15 +272,15 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
long txTimestamp = System.currentTimeMillis();
|
||||
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();
|
||||
|
||||
if ( useMinimalAPI ) {
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE2, txTimestamp, new Integer( 2 ), true );
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE2, txTimestamp, new Integer( 2 ), true );
|
||||
}
|
||||
else {
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE2, txTimestamp, new Integer( 2 ) );
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE2, txTimestamp, new Integer( 2 ) );
|
||||
}
|
||||
|
||||
BatchModeTransactionManager.getInstance().commit();
|
||||
|
@ -302,7 +310,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
long txTimestamp = System.currentTimeMillis();
|
||||
BatchModeTransactionManager.getInstance().begin();
|
||||
|
||||
assertNull( "node2 starts clean", remoteAccessStrategy.get(null, KEY, txTimestamp ) );
|
||||
assertNull( "node2 starts clean", remoteAccessStrategy.get(remoteSession, KEY, txTimestamp ) );
|
||||
|
||||
// Let node1 write
|
||||
writeLatch1.countDown();
|
||||
|
@ -313,10 +321,10 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
sleep( 200 );
|
||||
|
||||
if ( useMinimalAPI ) {
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer( 1 ), true );
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer( 1 ), true );
|
||||
}
|
||||
else {
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer( 1 ) );
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer( 1 ) );
|
||||
}
|
||||
|
||||
BatchModeTransactionManager.getInstance().commit();
|
||||
|
@ -376,8 +384,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
expected2 = VALUE2;
|
||||
}
|
||||
|
||||
assertEquals( msg1, expected1, localAccessStrategy.get(null, KEY, txTimestamp ) );
|
||||
assertEquals( msg2, expected2, remoteAccessStrategy.get(null, KEY, txTimestamp ) );
|
||||
assertEquals( msg1, expected1, localAccessStrategy.get(localSession, KEY, txTimestamp ) );
|
||||
assertEquals( msg2, expected2, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -404,13 +412,13 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
|
||||
final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ );
|
||||
|
||||
assertNull( "local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
assertNull( "remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
assertNull( "local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
|
||||
assertNull( "remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
|
||||
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
|
||||
|
||||
// Wait for async propagation
|
||||
sleep( 250 );
|
||||
|
@ -421,14 +429,14 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
if (evict)
|
||||
localAccessStrategy.evict(KEY);
|
||||
else
|
||||
localAccessStrategy.remove(null, KEY);
|
||||
localAccessStrategy.remove(localSession, KEY);
|
||||
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 {
|
||||
|
@ -439,13 +447,13 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
|
||||
assertEquals( 0, remoteCollectionRegion.getCache().size() );
|
||||
|
||||
assertNull( "local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
assertNull( "remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
assertNull( "local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
|
||||
assertNull( "remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
|
||||
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis() ) );
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
|
||||
|
||||
// Wait for async propagation
|
||||
sleep( 250 );
|
||||
|
@ -462,13 +470,13 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
});
|
||||
|
||||
// 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() );
|
||||
|
||||
// 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
|
||||
assertEquals( null, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
assertEquals( null, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
|
||||
|
||||
assertEquals( 0, remoteCollectionRegion.getCache().size() );
|
||||
|
||||
|
@ -476,8 +484,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
sleep( 250 );
|
||||
|
||||
// Test whether the get above messes up the optimistic version
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
|
||||
assertEquals( VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis() ) );
|
||||
|
||||
assertEquals( 1, remoteCollectionRegion.getCache().size() );
|
||||
|
||||
|
@ -486,11 +494,11 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
|
||||
assertEquals(
|
||||
"local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(
|
||||
null, KEY, System
|
||||
localSession, KEY, System
|
||||
.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() {
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.cache.internal.CacheDataDescriptionImpl;
|
|||
import org.hibernate.cache.spi.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.internal.util.compare.ComparableComparator;
|
||||
import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase;
|
||||
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.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Base class for tests of EntityRegionAccessStrategy impls.
|
||||
|
@ -62,10 +64,12 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
protected NodeEnvironment localEnvironment;
|
||||
protected EntityRegionImpl localEntityRegion;
|
||||
protected EntityRegionAccessStrategy localAccessStrategy;
|
||||
protected SessionImplementor localSession;
|
||||
|
||||
protected NodeEnvironment remoteEnvironment;
|
||||
protected EntityRegionImpl remoteEntityRegion;
|
||||
protected EntityRegionAccessStrategy remoteAccessStrategy;
|
||||
protected SessionImplementor remoteSession;
|
||||
|
||||
protected boolean invalidation;
|
||||
protected boolean synchronous;
|
||||
|
@ -85,6 +89,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
|
||||
localEntityRegion = localEnvironment.getEntityRegion(REGION_NAME, getCacheDataDescription());
|
||||
localAccessStrategy = localEntityRegion.buildAccessStrategy(getAccessType());
|
||||
localSession = mock(SessionImplementor.class);
|
||||
remoteSession = mock(SessionImplementor.class);
|
||||
|
||||
|
||||
invalidation = Caches.isInvalidationCache(localEntityRegion.getCache());
|
||||
synchronous = Caches.isSynchronousCache(localEntityRegion.getCache());
|
||||
|
@ -211,17 +218,17 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
long txTimestamp = System.currentTimeMillis();
|
||||
BatchModeTransactionManager.getInstance().begin();
|
||||
|
||||
assertNull("node1 starts clean", localAccessStrategy.get(null, KEY, txTimestamp));
|
||||
assertNull("node1 starts clean", localAccessStrategy.get(localSession, KEY, txTimestamp));
|
||||
|
||||
writeLatch1.await();
|
||||
|
||||
if (useMinimalAPI) {
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer(1), true);
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, txTimestamp, new Integer(1), true);
|
||||
} 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();
|
||||
} catch (Exception e) {
|
||||
|
@ -248,7 +255,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
long txTimestamp = System.currentTimeMillis();
|
||||
BatchModeTransactionManager.getInstance().begin();
|
||||
|
||||
assertNull("node1 starts clean", remoteAccessStrategy.get(null, KEY, txTimestamp));
|
||||
assertNull("node1 starts clean", remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
|
||||
|
||||
// Let node1 write
|
||||
writeLatch1.countDown();
|
||||
|
@ -256,9 +263,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
writeLatch2.await();
|
||||
|
||||
if (useMinimalAPI) {
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer(1), true);
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer(1), true);
|
||||
} else {
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, new Integer(1));
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, txTimestamp, new Integer(1));
|
||||
}
|
||||
|
||||
BatchModeTransactionManager.getInstance().commit();
|
||||
|
@ -286,14 +293,14 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
assertThreadsRanCleanly();
|
||||
|
||||
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()) {
|
||||
// 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 {
|
||||
// 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();
|
||||
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();
|
||||
commitLatch.await();
|
||||
|
@ -351,7 +358,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
|
||||
assertEquals(
|
||||
"Correct initial value", expected, localAccessStrategy.get(
|
||||
null, KEY,
|
||||
localSession, KEY,
|
||||
txTimestamp
|
||||
)
|
||||
);
|
||||
|
@ -381,9 +388,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
assertThreadsRanCleanly();
|
||||
|
||||
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;
|
||||
assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(null, KEY, txTimestamp));
|
||||
assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -392,8 +399,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
|
||||
|
||||
// Set up initial state
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
|
||||
// Let the async put propagate
|
||||
sleep(250);
|
||||
|
@ -411,9 +418,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
long txTimestamp = System.currentTimeMillis();
|
||||
BatchModeTransactionManager.getInstance().begin();
|
||||
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");
|
||||
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");
|
||||
readLatch.countDown();
|
||||
readerUnlocked = true;
|
||||
|
@ -450,7 +457,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
|
||||
// This won't block w/ mvc and will read the old value
|
||||
Object expected = VALUE1;
|
||||
assertEquals("Correct value", expected, localAccessStrategy.get(null, KEY, txTimestamp));
|
||||
assertEquals("Correct value", expected, localAccessStrategy.get(localSession, KEY, txTimestamp));
|
||||
|
||||
BatchModeTransactionManager.getInstance().commit();
|
||||
} catch (Exception e) {
|
||||
|
@ -479,9 +486,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
assertThreadsRanCleanly();
|
||||
|
||||
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;
|
||||
assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(null, KEY, txTimestamp));
|
||||
assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(remoteSession, KEY, txTimestamp));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -509,13 +516,13 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
assertEquals(0, localEntityRegion.getCache().size());
|
||||
assertEquals(0, remoteEntityRegion.getCache().size());
|
||||
|
||||
assertNull("local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertNull("remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertNull("local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
|
||||
assertNull("remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
|
||||
Caches.withinTx(localEntityRegion.getTransactionManager(), new Callable<Void>() {
|
||||
@Override
|
||||
|
@ -523,13 +530,13 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
if (evict)
|
||||
localAccessStrategy.evict(KEY);
|
||||
else
|
||||
localAccessStrategy.remove(null, KEY);
|
||||
localAccessStrategy.remove(localSession, KEY);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
assertEquals(null, localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertEquals(null, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -537,17 +544,17 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
|
||||
assertEquals(0, localEntityRegion.getCache().size());
|
||||
assertEquals(0, remoteEntityRegion.getCache().size());
|
||||
assertNull("local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertNull("remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertNull("local is clean", localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
|
||||
assertNull("remote is clean", remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
|
||||
|
||||
// Wait for async propagation
|
||||
sleep(250);
|
||||
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
|
||||
// Wait for async propagation
|
||||
sleep(250);
|
||||
|
@ -566,20 +573,20 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
});
|
||||
|
||||
// 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());
|
||||
|
||||
// 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
|
||||
assertNull(remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertNull(remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
assertEquals(0, remoteEntityRegion.getCache().size());
|
||||
|
||||
// Wait for async propagation of EndInvalidationCommand before executing naked put
|
||||
sleep(250);
|
||||
|
||||
// Test whether the get above messes up the optimistic version
|
||||
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
remoteAccessStrategy.putFromLoad(remoteSession, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
assertEquals(1, remoteEntityRegion.getCache().size());
|
||||
|
||||
// Wait for async propagation
|
||||
|
@ -587,11 +594,11 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
|
||||
assertEquals(
|
||||
"local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy
|
||||
.get(null, KEY, System.currentTimeMillis())
|
||||
.get(localSession, KEY, System.currentTimeMillis())
|
||||
);
|
||||
assertEquals(
|
||||
"remote is correct", VALUE1, remoteAccessStrategy.get(
|
||||
null, KEY, System
|
||||
remoteSession, KEY, System
|
||||
.currentTimeMillis()
|
||||
)
|
||||
);
|
||||
|
|
|
@ -45,26 +45,26 @@ public abstract class AbstractReadOnlyAccessTestCase extends AbstractEntityRegio
|
|||
|
||||
long txTimestamp = System.currentTimeMillis();
|
||||
BatchModeTransactionManager.getInstance().begin();
|
||||
assertNull(localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertNull(localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
|
||||
if (minimal)
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, 1, true);
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, txTimestamp, 1, true);
|
||||
else
|
||||
localAccessStrategy.putFromLoad(null, KEY, VALUE1, txTimestamp, 1);
|
||||
localAccessStrategy.putFromLoad(localSession, KEY, VALUE1, txTimestamp, 1);
|
||||
|
||||
sleep(250);
|
||||
Object expected = isUsingInvalidation() ? null : VALUE1;
|
||||
assertEquals(expected, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertEquals(expected, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
|
||||
BatchModeTransactionManager.getInstance().commit();
|
||||
assertEquals(VALUE1, localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertEquals(expected, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
|
||||
assertEquals(VALUE1, localAccessStrategy.get(localSession, KEY, System.currentTimeMillis()));
|
||||
assertEquals(expected, remoteAccessStrategy.get(remoteSession, KEY, System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
@Override
|
||||
public void testUpdate() throws Exception {
|
||||
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++ );
|
||||
|
||||
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 pferCompletionLatch = new CountDownLatch(1);
|
||||
|
@ -52,9 +52,9 @@ public abstract class AbstractTransactionalAccessTestCase extends AbstractEntity
|
|||
long txTimestamp = System.currentTimeMillis();
|
||||
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();
|
||||
commitLatch.await();
|
||||
|
|
Loading…
Reference in New Issue