HHH-4508 - Fixed 'avalable' typo
git-svn-id: https://svn.jboss.org/repos/hibernate/core/branches/Branch_3_3@17804 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
1bf135296a
commit
725e2a82d9
|
@ -23,9 +23,13 @@
|
|||
*/
|
||||
package org.hibernate.cache.jbc2;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.Transaction;
|
||||
|
@ -42,7 +46,12 @@ import org.jboss.cache.NodeSPI;
|
|||
import org.jboss.cache.config.Configuration;
|
||||
import org.jboss.cache.config.Option;
|
||||
import org.jboss.cache.config.Configuration.NodeLockingScheme;
|
||||
import org.jboss.cache.notifications.annotation.CacheListener;
|
||||
import org.jboss.cache.notifications.annotation.NodeInvalidated;
|
||||
import org.jboss.cache.notifications.annotation.NodeModified;
|
||||
import org.jboss.cache.notifications.annotation.ViewChanged;
|
||||
import org.jboss.cache.notifications.event.NodeInvalidatedEvent;
|
||||
import org.jboss.cache.notifications.event.NodeModifiedEvent;
|
||||
import org.jboss.cache.notifications.event.ViewChangedEvent;
|
||||
import org.jboss.cache.optimistic.DataVersion;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -53,30 +62,52 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@CacheListener
|
||||
public abstract class BasicRegionAdapter implements Region {
|
||||
|
||||
private enum InvalidateState { INVALID, CLEARING, VALID };
|
||||
|
||||
public static final String ITEM = CacheHelper.ITEM;
|
||||
|
||||
protected final Cache jbcCache;
|
||||
protected final String regionName;
|
||||
protected final Fqn regionFqn;
|
||||
protected final Fqn internalFqn;
|
||||
protected Node regionRoot;
|
||||
protected final boolean optimistic;
|
||||
protected final TransactionManager transactionManager;
|
||||
protected final Logger log;
|
||||
protected final Object regionRootMutex = new Object();
|
||||
protected final Object memberId;
|
||||
protected final boolean replication;
|
||||
protected final Object invalidationMutex = new Object();
|
||||
protected final AtomicReference<InvalidateState> invalidateState =
|
||||
new AtomicReference<InvalidateState>(InvalidateState.VALID);
|
||||
protected final Set<Object> currentView = new HashSet<Object>();
|
||||
|
||||
// protected RegionRootListener listener;
|
||||
|
||||
public BasicRegionAdapter(Cache jbcCache, String regionName, String regionPrefix) {
|
||||
|
||||
this.log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
this.jbcCache = jbcCache;
|
||||
this.transactionManager = jbcCache.getConfiguration().getRuntimeConfig().getTransactionManager();
|
||||
this.regionName = regionName;
|
||||
this.regionFqn = createRegionFqn(regionName, regionPrefix);
|
||||
optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
|
||||
log = LoggerFactory.getLogger(getClass());
|
||||
this.internalFqn = CacheHelper.getInternalFqn(regionFqn);
|
||||
this.optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
|
||||
this.memberId = jbcCache.getLocalAddress();
|
||||
this.replication = CacheHelper.isClusteredReplication(jbcCache);
|
||||
|
||||
this.jbcCache.addCacheListener(this);
|
||||
|
||||
synchronized (currentView) {
|
||||
List view = jbcCache.getMembers();
|
||||
if (view != null) {
|
||||
currentView.addAll(view);
|
||||
}
|
||||
}
|
||||
|
||||
activateLocalClusterNode();
|
||||
|
||||
log.debug("Created Region for " + regionName + " -- regionPrefix is " + regionPrefix);
|
||||
|
@ -129,13 +160,13 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
if (!regionRoot.isResident()) {
|
||||
regionRoot.setResident(true);
|
||||
}
|
||||
establishInternalNodes();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new CacheException(e.getMessage(), e);
|
||||
}
|
||||
finally {
|
||||
if (tx != null)
|
||||
resume(tx);
|
||||
resume(tx);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -154,6 +185,7 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
// For pessimistic locking, we just want to toss out our ref
|
||||
// to any old invalid root node and get the latest (may be null)
|
||||
if (!optimistic) {
|
||||
establishInternalNodes();
|
||||
regionRoot = jbcCache.getRoot().getChild( regionFqn );
|
||||
return;
|
||||
}
|
||||
|
@ -181,6 +213,7 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
}
|
||||
// Never evict this node
|
||||
newRoot.setResident(true);
|
||||
establishInternalNodes();
|
||||
}
|
||||
finally {
|
||||
resume(tx);
|
||||
|
@ -189,6 +222,24 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
}
|
||||
}
|
||||
|
||||
private void establishInternalNodes()
|
||||
{
|
||||
synchronized (currentView) {
|
||||
Transaction tx = suspend();
|
||||
try {
|
||||
for (Object member : currentView) {
|
||||
DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
|
||||
Fqn f = Fqn.fromRelativeElements(internalFqn, member);
|
||||
CacheHelper.addNode(jbcCache, f, true, false, version);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resume(tx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return regionName;
|
||||
}
|
||||
|
@ -201,6 +252,11 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
return regionFqn;
|
||||
}
|
||||
|
||||
public Object getMemberId()
|
||||
{
|
||||
return this.memberId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for the validity of the root cache node for this region,
|
||||
* creating a new one if it does not exist or is invalid, and also
|
||||
|
@ -219,6 +275,37 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
if (regionRoot != null && regionRoot.isValid() && !regionRoot.isResident())
|
||||
regionRoot.setResident(true);
|
||||
}
|
||||
|
||||
public boolean checkValid()
|
||||
{
|
||||
boolean valid = invalidateState.get() == InvalidateState.VALID;
|
||||
|
||||
if (!valid) {
|
||||
synchronized (invalidationMutex) {
|
||||
if (invalidateState.compareAndSet(InvalidateState.INVALID, InvalidateState.CLEARING)) {
|
||||
Transaction tx = suspend();
|
||||
try {
|
||||
Option opt = new Option();
|
||||
opt.setLockAcquisitionTimeout(1);
|
||||
opt.setCacheModeLocal(true);
|
||||
CacheHelper.removeAll(jbcCache, regionFqn, opt);
|
||||
invalidateState.compareAndSet(InvalidateState.CLEARING, InvalidateState.VALID);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Could not invalidate region: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resume(tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
valid = invalidateState.get() == InvalidateState.VALID;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void destroy() throws CacheException {
|
||||
try {
|
||||
|
@ -242,10 +329,9 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
} catch (Exception e) {
|
||||
throw new CacheException(e);
|
||||
}
|
||||
// finally {
|
||||
// if (listener != null)
|
||||
// jbcCache.removeCacheListener(listener);
|
||||
// }
|
||||
finally {
|
||||
jbcCache.removeCacheListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deactivateLocalNode() {
|
||||
|
@ -256,18 +342,50 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean contains(Object key) {
|
||||
if ( !checkValid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Option opt = new Option();
|
||||
opt.setLockAcquisitionTimeout(100);
|
||||
CacheHelper.setInvocationOption( jbcCache, opt );
|
||||
return CacheHelper.getAllowingTimeout( jbcCache, regionFqn, key ) != null;
|
||||
}
|
||||
catch ( CacheException ce ) {
|
||||
throw ce;
|
||||
}
|
||||
catch ( Throwable t ) {
|
||||
throw new CacheException( t );
|
||||
}
|
||||
}
|
||||
|
||||
public long getSizeInMemory() {
|
||||
// not supported
|
||||
return -1;
|
||||
}
|
||||
|
||||
public long getElementCountInMemory() {
|
||||
try {
|
||||
Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
|
||||
return childrenNames.size();
|
||||
} catch (Exception e) {
|
||||
throw new CacheException(e);
|
||||
if (checkValid()) {
|
||||
try {
|
||||
Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
|
||||
int size = childrenNames.size();
|
||||
if (childrenNames.contains(CacheHelper.Internal.NODE)) {
|
||||
size--;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
catch ( CacheException ce ) {
|
||||
throw ce;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new CacheException(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public long getElementCountOnDisk() {
|
||||
|
@ -275,17 +393,24 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
}
|
||||
|
||||
public Map toMap() {
|
||||
try {
|
||||
Map result = new HashMap();
|
||||
Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
|
||||
for (Object childName : childrenNames) {
|
||||
result.put(childName, CacheHelper.get(jbcCache,regionFqn, childName));
|
||||
}
|
||||
return result;
|
||||
} catch (CacheException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new CacheException(e);
|
||||
if (checkValid()) {
|
||||
try {
|
||||
Map result = new HashMap();
|
||||
Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
|
||||
for (Object childName : childrenNames) {
|
||||
if (CacheHelper.Internal.NODE != childName) {
|
||||
result.put(childName, CacheHelper.get(jbcCache,regionFqn, childName));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} catch (CacheException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new CacheException(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,7 +452,7 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
* @return the transaction that was suspended, or <code>null</code> if
|
||||
* there wasn't one
|
||||
*/
|
||||
protected Transaction suspend() {
|
||||
public Transaction suspend() {
|
||||
Transaction tx = null;
|
||||
try {
|
||||
if (transactionManager != null) {
|
||||
|
@ -345,7 +470,7 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
* @param tx
|
||||
* the transaction to suspend. May be <code>null</code>.
|
||||
*/
|
||||
protected void resume(Transaction tx) {
|
||||
public void resume(Transaction tx) {
|
||||
try {
|
||||
if (tx != null)
|
||||
transactionManager.resume(tx);
|
||||
|
@ -404,17 +529,52 @@ public abstract class BasicRegionAdapter implements Region {
|
|||
return escaped;
|
||||
}
|
||||
|
||||
// @CacheListener
|
||||
// public class RegionRootListener {
|
||||
//
|
||||
// @NodeCreated
|
||||
// public void nodeCreated(NodeCreatedEvent event) {
|
||||
// if (!event.isPre() && event.getFqn().equals(getRegionFqn())) {
|
||||
// log.debug("Node created for " + getRegionFqn());
|
||||
// Node regionRoot = jbcCache.getRoot().getChild(getRegionFqn());
|
||||
// regionRoot.setResident(true);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
@NodeModified
|
||||
public void nodeModified(NodeModifiedEvent event)
|
||||
{
|
||||
handleEvictAllModification(event);
|
||||
}
|
||||
|
||||
protected boolean handleEvictAllModification(NodeModifiedEvent event) {
|
||||
|
||||
if (!event.isPre() && (replication || event.isOriginLocal()) && event.getData().containsKey(ITEM))
|
||||
{
|
||||
if (event.getFqn().isChildOf(internalFqn))
|
||||
{
|
||||
invalidateState.set(InvalidateState.INVALID);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NodeInvalidated
|
||||
public void nodeInvalidated(NodeInvalidatedEvent event)
|
||||
{
|
||||
handleEvictAllInvalidation(event);
|
||||
}
|
||||
|
||||
protected boolean handleEvictAllInvalidation(NodeInvalidatedEvent event)
|
||||
{
|
||||
if (!event.isPre() && event.getFqn().isChildOf(internalFqn))
|
||||
{
|
||||
invalidateState.set(InvalidateState.INVALID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ViewChanged
|
||||
public void viewChanged(ViewChangedEvent event) {
|
||||
|
||||
synchronized (currentView) {
|
||||
List view = event.getNewView().getMembers();
|
||||
if (view != null) {
|
||||
currentView.addAll(view);
|
||||
establishInternalNodes();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,12 @@
|
|||
*/
|
||||
package org.hibernate.cache.jbc2.access;
|
||||
|
||||
import javax.transaction.Transaction;
|
||||
|
||||
import org.hibernate.cache.CacheDataDescription;
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
|
||||
import org.hibernate.cache.access.EntityRegionAccessStrategy;
|
||||
import org.hibernate.cache.jbc2.BasicRegionAdapter;
|
||||
import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
|
||||
import org.hibernate.cache.jbc2.util.CacheHelper;
|
||||
import org.hibernate.cache.jbc2.util.DataVersionAdapter;
|
||||
|
@ -75,22 +76,17 @@ public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDe
|
|||
* by adding a {@link NonLockingDataVersion} to the invocation.
|
||||
*/
|
||||
@Override
|
||||
public void evictAll() throws CacheException {
|
||||
|
||||
evictOrRemoveAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the {@link TransactionalAccessDelegate#get(Object, long) superclass}
|
||||
* by {@link BasicRegionAdapter#ensureRegionRootExists() ensuring the root
|
||||
* node for the region exists} before making the call.
|
||||
*/
|
||||
@Override
|
||||
public Object get(Object key, long txTimestamp) throws CacheException
|
||||
public void evictAll() throws CacheException
|
||||
{
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
return CacheHelper.get(cache, regionFqn, key);
|
||||
Transaction tx = region.suspend();
|
||||
try {
|
||||
region.ensureRegionRootExists();
|
||||
Option opt = NonLockingDataVersion.getInvocationOption();
|
||||
CacheHelper.sendEvictAllNotification(cache, regionFqn, region.getMemberId(), opt);
|
||||
}
|
||||
finally {
|
||||
region.resume(tx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,6 +96,9 @@ public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDe
|
|||
*/
|
||||
@Override
|
||||
public boolean insert(Object key, Object value, Object version) throws CacheException {
|
||||
|
||||
if (!region.checkValid())
|
||||
return false;
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
|
@ -111,6 +110,9 @@ public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDe
|
|||
@Override
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
|
||||
throws CacheException {
|
||||
|
||||
if (!region.checkValid())
|
||||
return false;
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
|
@ -123,6 +125,9 @@ public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDe
|
|||
|
||||
@Override
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
|
||||
|
||||
if (!region.checkValid())
|
||||
return false;
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
|
@ -132,6 +137,10 @@ public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDe
|
|||
|
||||
@Override
|
||||
public void remove(Object key) throws CacheException {
|
||||
|
||||
// We remove whether or not the region is valid. Other nodes
|
||||
// may have already restored the region so they need to
|
||||
// be informed of the change.
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
|
@ -141,14 +150,18 @@ public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDe
|
|||
|
||||
@Override
|
||||
public void removeAll() throws CacheException {
|
||||
|
||||
evictOrRemoveAll();
|
||||
Option opt = NonLockingDataVersion.getInvocationOption();
|
||||
CacheHelper.removeAll(cache, regionFqn, opt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
|
||||
throws CacheException {
|
||||
|
||||
// We update whether or not the region is valid. Other nodes
|
||||
// may have already restored the region so they need to
|
||||
// be informed of the change.
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
Option opt = getDataVersionOption(currentVersion, previousVersion);
|
||||
|
@ -166,10 +179,4 @@ public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDe
|
|||
return opt;
|
||||
}
|
||||
|
||||
private void evictOrRemoveAll() {
|
||||
|
||||
Option opt = NonLockingDataVersion.getInvocationOption();
|
||||
CacheHelper.removeAll(cache, regionFqn, opt);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.cache.jbc2.access;
|
||||
|
||||
import javax.transaction.Transaction;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
|
||||
import org.hibernate.cache.access.EntityRegionAccessStrategy;
|
||||
|
@ -56,13 +58,19 @@ public class TransactionalAccessDelegate {
|
|||
}
|
||||
|
||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
||||
|
||||
|
||||
if (!region.checkValid())
|
||||
return null;
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
return CacheHelper.get(cache, regionFqn, key);
|
||||
}
|
||||
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
|
||||
|
||||
if (!region.checkValid())
|
||||
return false;
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
|
@ -72,6 +80,9 @@ public class TransactionalAccessDelegate {
|
|||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
|
||||
throws CacheException {
|
||||
|
||||
if (!region.checkValid())
|
||||
return false;
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
// We ignore minimalPutOverride. JBossCache putForExternalRead is
|
||||
|
@ -96,6 +107,9 @@ public class TransactionalAccessDelegate {
|
|||
|
||||
public boolean insert(Object key, Object value, Object version) throws CacheException {
|
||||
|
||||
if (!region.checkValid())
|
||||
return false;
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
CacheHelper.put(cache, regionFqn, key, value);
|
||||
|
@ -109,6 +123,10 @@ public class TransactionalAccessDelegate {
|
|||
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
|
||||
throws CacheException {
|
||||
|
||||
// We update whether or not the region is valid. Other nodes
|
||||
// may have already restored the region so they need to
|
||||
// be informed of the change.
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
CacheHelper.put(cache, regionFqn, key, value);
|
||||
|
@ -122,13 +140,17 @@ public class TransactionalAccessDelegate {
|
|||
|
||||
public void remove(Object key) throws CacheException {
|
||||
|
||||
// We remove whether or not the region is valid. Other nodes
|
||||
// may have already restored the region so they need to
|
||||
// be informed of the change.
|
||||
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
CacheHelper.remove(cache, regionFqn, key);
|
||||
}
|
||||
|
||||
public void removeAll() throws CacheException {
|
||||
evictOrRemoveAll();
|
||||
CacheHelper.removeAll(cache, regionFqn);
|
||||
}
|
||||
|
||||
public void evict(Object key) throws CacheException {
|
||||
|
@ -139,10 +161,15 @@ public class TransactionalAccessDelegate {
|
|||
}
|
||||
|
||||
public void evictAll() throws CacheException {
|
||||
evictOrRemoveAll();
|
||||
Transaction tx = region.suspend();
|
||||
try {
|
||||
region.ensureRegionRootExists();
|
||||
|
||||
CacheHelper.sendEvictAllNotification(cache, regionFqn, region.getMemberId(), null);
|
||||
}
|
||||
finally {
|
||||
region.resume(tx);
|
||||
}
|
||||
}
|
||||
|
||||
private void evictOrRemoveAll() throws CacheException {
|
||||
CacheHelper.removeAll(cache, regionFqn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.cache.jbc2.collection;
|
|||
import org.jboss.cache.Cache;
|
||||
import org.jboss.cache.Fqn;
|
||||
import org.jboss.cache.config.Configuration.NodeLockingScheme;
|
||||
import org.jboss.cache.notifications.annotation.CacheListener;
|
||||
|
||||
import org.hibernate.cache.CacheDataDescription;
|
||||
import org.hibernate.cache.CacheException;
|
||||
|
@ -39,6 +40,7 @@ import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@CacheListener
|
||||
public class CollectionRegionImpl extends TransactionalDataRegionAdapter implements CollectionRegion {
|
||||
|
||||
public static final String TYPE = "COLL";
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.cache.jbc2.entity;
|
|||
import org.jboss.cache.Cache;
|
||||
import org.jboss.cache.Fqn;
|
||||
import org.jboss.cache.config.Configuration.NodeLockingScheme;
|
||||
import org.jboss.cache.notifications.annotation.CacheListener;
|
||||
|
||||
import org.hibernate.cache.CacheDataDescription;
|
||||
import org.hibernate.cache.CacheException;
|
||||
|
@ -39,6 +40,7 @@ import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@CacheListener
|
||||
public class EntityRegionImpl extends TransactionalDataRegionAdapter implements EntityRegion {
|
||||
|
||||
public static final String TYPE = "ENTITY";
|
||||
|
|
|
@ -25,6 +25,8 @@ package org.hibernate.cache.jbc2.query;
|
|||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.transaction.Transaction;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.QueryResultsRegion;
|
||||
import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
|
||||
|
@ -33,6 +35,7 @@ import org.hibernate.util.PropertiesHelper;
|
|||
import org.jboss.cache.Cache;
|
||||
import org.jboss.cache.Fqn;
|
||||
import org.jboss.cache.config.Option;
|
||||
import org.jboss.cache.notifications.annotation.CacheListener;
|
||||
|
||||
/**
|
||||
* Defines the behavior of the query cache regions for JBossCache 2.x.
|
||||
|
@ -40,6 +43,7 @@ import org.jboss.cache.config.Option;
|
|||
* @author Brian Stansberry
|
||||
* @version $Revision$
|
||||
*/
|
||||
@CacheListener
|
||||
public class QueryResultsRegionImpl extends TransactionalDataRegionAdapter implements QueryResultsRegion {
|
||||
|
||||
public static final String QUERY_CACHE_LOCAL_ONLY_PROP = "hibernate.cache.region.jbc2.query.localonly";
|
||||
|
@ -85,14 +89,22 @@ public class QueryResultsRegionImpl extends TransactionalDataRegionAdapter imple
|
|||
}
|
||||
|
||||
public void evictAll() throws CacheException {
|
||||
Option opt = getNonLockingDataVersionOption(false);
|
||||
if (localOnly)
|
||||
opt.setCacheModeLocal(true);
|
||||
CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
|
||||
Transaction tx = suspend();
|
||||
try {
|
||||
ensureRegionRootExists();
|
||||
Option opt = getNonLockingDataVersionOption(true);
|
||||
CacheHelper.sendEvictAllNotification(jbcCache, regionFqn, getMemberId(), opt);
|
||||
}
|
||||
finally {
|
||||
resume(tx);
|
||||
}
|
||||
}
|
||||
|
||||
public Object get(Object key) throws CacheException {
|
||||
|
||||
if (!checkValid())
|
||||
return null;
|
||||
|
||||
ensureRegionRootExists();
|
||||
|
||||
// Don't hold the JBC node lock throughout the tx, as that
|
||||
|
@ -106,28 +118,30 @@ public class QueryResultsRegionImpl extends TransactionalDataRegionAdapter imple
|
|||
|
||||
public void put(Object key, Object value) throws CacheException {
|
||||
|
||||
ensureRegionRootExists();
|
||||
|
||||
// Here we don't want to suspend the tx. If we do:
|
||||
// 1) We might be caching query results that reflect uncommitted
|
||||
// changes. No tx == no WL on cache node, so other threads
|
||||
// can prematurely see those query results
|
||||
// 2) No tx == immediate replication. More overhead, plus we
|
||||
// spread issue #1 above around the cluster
|
||||
|
||||
// Add a zero (or quite low) timeout option so we don't block.
|
||||
// Ignore any TimeoutException. Basically we forego caching the
|
||||
// query result in order to avoid blocking.
|
||||
// Reads are done with suspended tx, so they should not hold the
|
||||
// lock for long. Not caching the query result is OK, since
|
||||
// any subsequent read will just see the old result with its
|
||||
// out-of-date timestamp; that result will be discarded and the
|
||||
// db query performed again.
|
||||
Option opt = getNonLockingDataVersionOption(false);
|
||||
opt.setLockAcquisitionTimeout(2);
|
||||
if (localOnly)
|
||||
opt.setCacheModeLocal(true);
|
||||
CacheHelper.putAllowingTimeout(getCacheInstance(), getRegionFqn(), key, value, opt);
|
||||
if (checkValid()) {
|
||||
ensureRegionRootExists();
|
||||
|
||||
// Here we don't want to suspend the tx. If we do:
|
||||
// 1) We might be caching query results that reflect uncommitted
|
||||
// changes. No tx == no WL on cache node, so other threads
|
||||
// can prematurely see those query results
|
||||
// 2) No tx == immediate replication. More overhead, plus we
|
||||
// spread issue #1 above around the cluster
|
||||
|
||||
// Add a zero (or quite low) timeout option so we don't block.
|
||||
// Ignore any TimeoutException. Basically we forego caching the
|
||||
// query result in order to avoid blocking.
|
||||
// Reads are done with suspended tx, so they should not hold the
|
||||
// lock for long. Not caching the query result is OK, since
|
||||
// any subsequent read will just see the old result with its
|
||||
// out-of-date timestamp; that result will be discarded and the
|
||||
// db query performed again.
|
||||
Option opt = getNonLockingDataVersionOption(false);
|
||||
opt.setLockAcquisitionTimeout(2);
|
||||
if (localOnly)
|
||||
opt.setCacheModeLocal(true);
|
||||
CacheHelper.putAllowingTimeout(getCacheInstance(), getRegionFqn(), key, value, opt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.jboss.cache.config.Option;
|
|||
import org.jboss.cache.notifications.annotation.CacheListener;
|
||||
import org.jboss.cache.notifications.annotation.NodeModified;
|
||||
import org.jboss.cache.notifications.annotation.NodeRemoved;
|
||||
import org.jboss.cache.notifications.event.NodeInvalidatedEvent;
|
||||
import org.jboss.cache.notifications.event.NodeModifiedEvent;
|
||||
import org.jboss.cache.notifications.event.NodeRemovedEvent;
|
||||
|
||||
|
@ -95,14 +96,21 @@ public class TimestampsRegionImpl extends TransactionalDataRegionAdapter impleme
|
|||
|
||||
public void evictAll() throws CacheException {
|
||||
// TODO Is this a valid operation on a timestamps cache?
|
||||
Option opt = getNonLockingDataVersionOption(true);
|
||||
CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
|
||||
Transaction tx = suspend();
|
||||
try {
|
||||
ensureRegionRootExists();
|
||||
Option opt = getNonLockingDataVersionOption(true);
|
||||
CacheHelper.sendEvictAllNotification(jbcCache, regionFqn, getMemberId(), opt);
|
||||
}
|
||||
finally {
|
||||
resume(tx);
|
||||
}
|
||||
}
|
||||
|
||||
public Object get(Object key) throws CacheException {
|
||||
|
||||
Object value = localCache.get(key);
|
||||
if (value == null) {
|
||||
if (value == null && checkValid()) {
|
||||
|
||||
ensureRegionRootExists();
|
||||
|
||||
|
@ -147,14 +155,15 @@ public class TimestampsRegionImpl extends TransactionalDataRegionAdapter impleme
|
|||
*/
|
||||
@NodeModified
|
||||
public void nodeModified(NodeModifiedEvent event) {
|
||||
if (event.isPre())
|
||||
return;
|
||||
|
||||
Fqn fqn = event.getFqn();
|
||||
Fqn regFqn = getRegionFqn();
|
||||
if (fqn.size() == regFqn.size() + 1 && fqn.isChildOf(regFqn)) {
|
||||
Object key = fqn.get(regFqn.size());
|
||||
localCache.put(key, event.getData().get(ITEM));
|
||||
|
||||
if (!handleEvictAllModification(event) && !event.isPre()) {
|
||||
|
||||
Fqn fqn = event.getFqn();
|
||||
Fqn regFqn = getRegionFqn();
|
||||
if (fqn.size() == regFqn.size() + 1 && fqn.isChildOf(regFqn)) {
|
||||
Object key = fqn.get(regFqn.size());
|
||||
localCache.put(key, event.getData().get(ITEM));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,8 +187,30 @@ public class TimestampsRegionImpl extends TransactionalDataRegionAdapter impleme
|
|||
localCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@Override
|
||||
protected boolean handleEvictAllInvalidation(NodeInvalidatedEvent event)
|
||||
{
|
||||
boolean result = super.handleEvictAllInvalidation(event);
|
||||
if (result) {
|
||||
localCache.clear();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleEvictAllModification(NodeModifiedEvent event)
|
||||
{
|
||||
boolean result = super.handleEvictAllModification(event);
|
||||
if (result) {
|
||||
localCache.clear();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Brings all data from the distributed cache into our local cache.
|
||||
*/
|
||||
private void populateLocalCache() {
|
||||
|
|
|
@ -46,6 +46,8 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
public class CacheHelper {
|
||||
|
||||
public static enum Internal { NODE, LOCAL };
|
||||
|
||||
/** Key under which items are cached */
|
||||
public static final String ITEM = "item";
|
||||
/** Key and value used in a hack to create region root nodes */
|
||||
|
@ -467,4 +469,23 @@ public class CacheHelper {
|
|||
option.setDataVersion(version);
|
||||
setInvocationOption(cache, option);
|
||||
}
|
||||
|
||||
public static Fqn getInternalFqn(Fqn region)
|
||||
{
|
||||
return Fqn.fromRelativeElements(region, Internal.NODE);
|
||||
}
|
||||
|
||||
public static void sendEvictNotification(Cache cache, Fqn region, Object member, Object key, Option option)
|
||||
{
|
||||
setInvocationOption(cache, option);
|
||||
Fqn f = Fqn.fromRelativeElements(region, Internal.NODE, member == null ? Internal.LOCAL : member, key);
|
||||
cache.put(f, ITEM, DUMMY);
|
||||
}
|
||||
|
||||
public static void sendEvictAllNotification(Cache cache, Fqn region, Object member, Option option)
|
||||
{
|
||||
setInvocationOption(cache, option);
|
||||
Fqn f = Fqn.fromRelativeElements(region, Internal.NODE, member == null ? Internal.LOCAL : member);
|
||||
cache.put(f, ITEM, DUMMY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,11 @@ public class DataVersionAdapter implements DataVersion {
|
|||
// treat as us being newer
|
||||
return (other.previousVersion != null);
|
||||
}
|
||||
|
||||
// Can't be newer than itself
|
||||
if ( this == dataVersion ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return versionComparator.compare(currentVersion, other.previousVersion) >= 1;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
package org.hibernate.test.cache.jbc2;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.GeneralDataRegion;
|
||||
import org.hibernate.cache.QueryResultsRegion;
|
||||
import org.hibernate.cache.Region;
|
||||
|
@ -171,8 +169,7 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
|
|||
|
||||
Node regionRoot = localCache.getRoot().getChild(regionFqn);
|
||||
assertFalse(regionRoot == null);
|
||||
Set children = regionRoot.getChildrenNames();
|
||||
assertEquals("No children in " + children, 0, children.size());
|
||||
assertEquals("No children in " + regionRoot, 0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isResident());
|
||||
|
||||
if (optimistic) {
|
||||
|
@ -181,7 +178,7 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
|
|||
|
||||
regionRoot = remoteCache.getRoot().getChild(regionFqn);
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, regionRoot.getChildrenNames().size());
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isResident());
|
||||
|
||||
if (optimistic) {
|
||||
|
@ -212,35 +209,24 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
|
|||
|
||||
localRegion.evictAll();
|
||||
|
||||
// This should re-establish the region root node in the optimistic case
|
||||
// This should re-establish the region root node
|
||||
assertNull(localRegion.get(KEY));
|
||||
|
||||
regionRoot = localCache.getRoot().getChild(regionFqn);
|
||||
if (optimistic) {
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, regionRoot.getChildrenNames().size());
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
}
|
||||
else {
|
||||
assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
|
||||
}
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
|
||||
// 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
|
||||
// This only adds a node in the case of optimistic locking
|
||||
assertEquals(null, remoteRegion.get(KEY));
|
||||
|
||||
regionRoot = remoteCache.getRoot().getChild(regionFqn);
|
||||
if (optimistic) {
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, regionRoot.getChildrenNames().size());
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
}
|
||||
else {
|
||||
assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
|
||||
}
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
|
||||
assertEquals("local is clean", null, localRegion.get(KEY));
|
||||
assertEquals("remote is clean", null, remoteRegion.get(KEY));
|
||||
|
|
|
@ -25,10 +25,14 @@ package org.hibernate.test.cache.jbc2;
|
|||
|
||||
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.cache.RegionFactory;
|
||||
import org.hibernate.cache.jbc2.util.CacheHelper;
|
||||
import org.hibernate.junit.UnitTestCase;
|
||||
import org.hibernate.test.util.CacheTestSupport;
|
||||
import org.jboss.cache.Cache;
|
||||
import org.jboss.cache.Node;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -96,4 +100,15 @@ public abstract class AbstractJBossCacheTestCase extends UnitTestCase {
|
|||
protected void avoidConcurrentFlush() {
|
||||
testSupport.avoidConcurrentFlush();
|
||||
}
|
||||
|
||||
protected int getValidChildrenCount(Node node) {
|
||||
int result = 0;
|
||||
Set<Node> children = node.getChildren();
|
||||
for (Node child : children) {
|
||||
if (node.isValid() && CacheHelper.Internal.NODE.equals(child.getFqn().getLastElement()) == false) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -471,38 +471,27 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
localAccessStrategy.evictAll();
|
||||
else
|
||||
localAccessStrategy.removeAll();
|
||||
|
||||
// This should re-establish the region root node in the optimistic case
|
||||
|
||||
// This should re-establish the region root node
|
||||
assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
|
||||
regionRoot = localCache.getRoot().getChild(regionFqn);
|
||||
if (isUsingOptimisticLocking()) {
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
}
|
||||
else {
|
||||
assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
|
||||
}
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
|
||||
// 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
|
||||
// This only adds a node in the case of optimistic locking
|
||||
assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
|
||||
regionRoot = remoteCache.getRoot().getChild(regionFqn);
|
||||
if (isUsingOptimisticLocking()) {
|
||||
assertFalse(regionRoot == null);
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
// Not invalidation, so we didn't insert a child above
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
}
|
||||
else {
|
||||
assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
|
||||
}
|
||||
|
||||
assertFalse(regionRoot == null);
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
// Not invalidation, so we didn't insert a child above
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
|
||||
// Test whether the get above messes up the optimistic version
|
||||
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
|
@ -521,17 +510,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
|
|||
assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
private int getValidChildrenCount(Node node) {
|
||||
int result = 0;
|
||||
for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
|
||||
if (((Node) it.next()).isValid()) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private void rollback() {
|
||||
try {
|
||||
BatchModeTransactionManager.getInstance().rollback();
|
||||
|
|
|
@ -682,36 +682,26 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
else
|
||||
localAccessStrategy.removeAll();
|
||||
|
||||
// This should re-establish the region root node in the optimistic case
|
||||
// This should re-establish the region root node
|
||||
assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
|
||||
regionRoot = localCache.getRoot().getChild(regionFqn);
|
||||
if (isUsingOptimisticLocking()) {
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
}
|
||||
else {
|
||||
assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
|
||||
}
|
||||
assertFalse(regionRoot == null);
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
|
||||
// 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(KEY, System.currentTimeMillis()));
|
||||
|
||||
regionRoot = remoteCache.getRoot().getChild(regionFqn);
|
||||
if (isUsingOptimisticLocking()) {
|
||||
assertFalse(regionRoot == null);
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
// Not invalidation, so we didn't insert a child above
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
}
|
||||
else {
|
||||
assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
|
||||
}
|
||||
|
||||
assertFalse(regionRoot == null);
|
||||
assertTrue(regionRoot.isValid());
|
||||
assertTrue(regionRoot.isResident());
|
||||
// Not invalidation, so we didn't insert a child above
|
||||
assertEquals(0, getValidChildrenCount(regionRoot));
|
||||
|
||||
// Test whether the get above messes up the optimistic version
|
||||
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
|
||||
assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
|
@ -730,17 +720,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
|
|||
assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
private int getValidChildrenCount(Node node) {
|
||||
int result = 0;
|
||||
for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
|
||||
if (((Node) it.next()).isValid()) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected void rollback() {
|
||||
try {
|
||||
BatchModeTransactionManager.getInstance().rollback();
|
||||
|
|
|
@ -63,7 +63,7 @@ public abstract class AbstractTransactionalAccessTestCase extends AbstractEntity
|
|||
final CountDownLatch commitLatch = new CountDownLatch(1);
|
||||
final CountDownLatch completionLatch = new CountDownLatch(1);
|
||||
|
||||
Thread blocker = new Thread() {
|
||||
Thread blocker = new Thread("Blocker") {
|
||||
|
||||
public void run() {
|
||||
|
||||
|
@ -95,7 +95,7 @@ public abstract class AbstractTransactionalAccessTestCase extends AbstractEntity
|
|||
}
|
||||
};
|
||||
|
||||
Thread putter = new Thread() {
|
||||
Thread putter = new Thread("Putter") {
|
||||
|
||||
public void run() {
|
||||
|
||||
|
|
|
@ -26,11 +26,11 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.cache.RegionFactory;
|
||||
import org.hibernate.cache.jbc2.MultiplexedJBossCacheRegionFactory;
|
||||
import org.hibernate.cache.jbc2.builder.MultiplexingCacheInstanceManager;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.classic.Session;
|
||||
import org.hibernate.stat.SecondLevelCacheStatistics;
|
||||
import org.hibernate.test.cache.jbc2.functional.CacheTestCaseBase;
|
||||
import org.hibernate.test.cache.jbc2.functional.Contact;
|
||||
import org.hibernate.test.cache.jbc2.functional.Customer;
|
||||
|
@ -90,7 +90,12 @@ extends CacheTestCaseBase
|
|||
assertNotNull("Red Hat contacts exist", rhContacts);
|
||||
assertEquals("Created expected number of Red Hat contacts", 10, rhContacts.size());
|
||||
|
||||
SecondLevelCacheStatistics contactSlcs = getEnvironment().getSessionFactory().getStatistics().getSecondLevelCacheStatistics(
|
||||
getPrefixedRegionName(Contact.class.getName()));
|
||||
assertEquals(contactSlcs.getElementCountInMemory(), 20);
|
||||
|
||||
assertEquals("Deleted all Red Hat contacts", 10, deleteContacts());
|
||||
assertEquals(0, contactSlcs.getElementCountInMemory());
|
||||
|
||||
List<Integer> jbContacts = getContactsByCustomer("JBoss");
|
||||
assertNotNull("JBoss contacts exist", jbContacts);
|
||||
|
@ -108,6 +113,7 @@ extends CacheTestCaseBase
|
|||
}
|
||||
|
||||
updateContacts("Kabir", "Updated");
|
||||
assertEquals(contactSlcs.getElementCountInMemory(), 0);
|
||||
for (Integer id : jbContacts)
|
||||
{
|
||||
Contact contact = getContact(id);
|
||||
|
@ -120,6 +126,21 @@ extends CacheTestCaseBase
|
|||
List<Integer> updated = getContactsByTLF("Updated");
|
||||
assertNotNull("Got updated contacts", updated);
|
||||
assertEquals("Updated contacts", 5, updated.size());
|
||||
|
||||
updateContactsWithOneManual("Kabir", "UpdatedAgain");
|
||||
assertEquals(contactSlcs.getElementCountInMemory(), 0);
|
||||
for (Integer id : jbContacts)
|
||||
{
|
||||
Contact contact = getContact(id);
|
||||
assertNotNull("JBoss contact " + id + " exists", contact);
|
||||
String expected = ("Kabir".equals(contact.getName())) ? "UpdatedAgain" : "2222";
|
||||
assertEquals("JBoss contact " + id + " has correct TLF",
|
||||
expected, contact.getTlf());
|
||||
}
|
||||
|
||||
updated = getContactsByTLF("UpdatedAgain");
|
||||
assertNotNull("Got updated contacts", updated);
|
||||
assertEquals("Updated contacts", 5, updated.size());
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -231,6 +252,34 @@ extends CacheTestCaseBase
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public int updateContactsWithOneManual(String name, String newTLF) throws Exception
|
||||
{
|
||||
String queryHQL = "from Contact c where c.name = :cName";
|
||||
String updateHQL = "update Contact set tlf = :cNewTLF where name = :cName";
|
||||
|
||||
SimpleJtaTransactionManagerImpl.getInstance().begin();
|
||||
try {
|
||||
|
||||
Session session = getSessions().getCurrentSession();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Contact> list = session.createQuery(queryHQL).setParameter("cName", name).list();
|
||||
list.get(0).setTlf(newTLF);
|
||||
|
||||
int rowsAffected = session.createQuery(updateHQL)
|
||||
.setFlushMode(FlushMode.AUTO)
|
||||
.setParameter("cNewTLF", newTLF)
|
||||
.setParameter("cName", name)
|
||||
.executeUpdate();
|
||||
SimpleJtaTransactionManagerImpl.getInstance().commit();
|
||||
return rowsAffected;
|
||||
}
|
||||
catch (Exception e) {
|
||||
SimpleJtaTransactionManagerImpl.getInstance().rollback();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public Contact getContact(Integer id) throws Exception
|
||||
{
|
||||
|
|
|
@ -124,10 +124,10 @@
|
|||
Number of milliseconds to wait until all responses for a
|
||||
synchronous call have been received.
|
||||
-->
|
||||
<attribute name="SyncReplTimeout">20000</attribute>
|
||||
<attribute name="SyncReplTimeout">10000</attribute>
|
||||
|
||||
<!-- Max number of milliseconds to wait for a lock acquisition -->
|
||||
<attribute name="LockAcquisitionTimeout">15000</attribute>
|
||||
<attribute name="LockAcquisitionTimeout">5000</attribute>
|
||||
|
||||
<!--
|
||||
Indicate whether to use marshalling or not. Set this to true if you are running under a scoped
|
||||
|
|
|
@ -105,10 +105,10 @@
|
|||
Number of milliseconds to wait until all responses for a
|
||||
synchronous call have been received.
|
||||
-->
|
||||
<attribute name="SyncReplTimeout">20000</attribute>
|
||||
<attribute name="SyncReplTimeout">10000</attribute>
|
||||
|
||||
<!-- Max number of milliseconds to wait for a lock acquisition -->
|
||||
<attribute name="LockAcquisitionTimeout">15000</attribute>
|
||||
<attribute name="LockAcquisitionTimeout">5000</attribute>
|
||||
|
||||
<!-- Specific eviction policy configurations. This is LRU -->
|
||||
<attribute name="EvictionPolicyConfig">
|
||||
|
|
|
@ -46,10 +46,6 @@ public class BytecodeProviderImpl implements BytecodeProvider {
|
|||
|
||||
private static final Logger log = LoggerFactory.getLogger( BytecodeProviderImpl.class );
|
||||
|
||||
public BytecodeProviderImpl() {
|
||||
log.warn( "The CGLIB BytecodeProvider impl is considered deprecated and not recommended for use" );
|
||||
}
|
||||
|
||||
public ProxyFactoryFactory getProxyFactoryFactory() {
|
||||
return new ProxyFactoryFactoryImpl();
|
||||
}
|
||||
|
|
|
@ -1089,6 +1089,15 @@ public abstract class Dialect {
|
|||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Command used to drop a temporary table.
|
||||
*
|
||||
* @return The command used to drop a temporary table.
|
||||
*/
|
||||
public String getDropTemporaryTableString() {
|
||||
return "drop table";
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the dialect require that temporary table DDL statements occur in
|
||||
* isolation from other statements? This would be the case if the creation
|
||||
|
|
|
@ -278,6 +278,16 @@ public class MySQLDialect extends Dialect {
|
|||
return "create temporary table if not exists";
|
||||
}
|
||||
|
||||
public String getDropTemporaryTableString() {
|
||||
return "drop temporary table";
|
||||
}
|
||||
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
// because we [drop *temporary* table...] we do not
|
||||
// have to perform these in isolation.
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public String getCastTypeName(int code) {
|
||||
if ( code==Types.INTEGER ) {
|
||||
return "signed";
|
||||
|
@ -321,10 +331,6 @@ public class MySQLDialect extends Dialect {
|
|||
return true;
|
||||
}
|
||||
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ public class DialectFactory {
|
|||
public static Dialect buildDialect(Properties properties) {
|
||||
String dialectName = properties.getProperty( Environment.DIALECT );
|
||||
if ( dialectName == null ) {
|
||||
throw new HibernateException( "'hibernate.dialect' must be set when no Connection avalable" );
|
||||
throw new HibernateException( "'hibernate.dialect' must be set when no Connection available" );
|
||||
}
|
||||
return constructDialect( dialectName );
|
||||
}
|
||||
|
|
|
@ -181,8 +181,10 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
|
|||
public void doWork(Connection connection) throws HibernateException {
|
||||
Statement stmnt = null;
|
||||
try {
|
||||
final String command = session.getFactory().getSettings().getDialect().getDropTemporaryTableString()
|
||||
+ " " + persister.getTemporaryIdTableName();
|
||||
stmnt = connection.createStatement();
|
||||
stmnt.executeUpdate( "drop table " + persister.getTemporaryIdTableName() );
|
||||
stmnt.executeUpdate( command );
|
||||
}
|
||||
catch( Throwable t ) {
|
||||
log.warn( "unable to drop temporary id table after use [" + t.getMessage() + "]" );
|
||||
|
|
|
@ -158,9 +158,9 @@
|
|||
|
||||
<para>
|
||||
Commercial development support, production support, and training for Hibernate is
|
||||
available through Red Hat Inc. (see http://www.hibernate.org/SupportTraining/).
|
||||
available through Red Hat, Inc. (see http://www.hibernate.org/SupportTraining/).
|
||||
Hibernate is a Professional Open Source project and a critical component of the
|
||||
JBoss Enterprise Middleware System (JEMS) suite of products.
|
||||
JBoss Enterprise Application Platform.
|
||||
</para>
|
||||
|
||||
</preface>
|
||||
|
|
|
@ -198,12 +198,30 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
<extensions>
|
||||
<!-- webdav based deployments (snapshot repo) -->
|
||||
<extension>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-webdav</artifactId>
|
||||
<version>1.0-beta-2</version>
|
||||
</extension>
|
||||
<!-- scm based deployments (release repo) -->
|
||||
<extension>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-scm</artifactId>
|
||||
<version>1.0-beta-6</version>
|
||||
</extension>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.scm</groupId>
|
||||
<artifactId>maven-scm-manager-plexus</artifactId>
|
||||
<version>1.0</version>
|
||||
</extension>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.scm</groupId>
|
||||
<artifactId>maven-scm-provider-svnexe</artifactId>
|
||||
<version>1.0</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
</build>
|
||||
|
||||
|
@ -351,11 +369,9 @@
|
|||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
|
||||
<!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
|
||||
<!-- todo : replace this with direct svn access once the svnkit providers are available -->
|
||||
<id>repository.jboss.org</id>
|
||||
<url>file://${maven.repository.root}</url>
|
||||
<name>JBoss Release Repository</name>
|
||||
<url>scm:svn:https://svn.jboss.org/repos/repository.jboss.org/maven2</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>snapshots.jboss.org</id>
|
||||
|
|
Loading…
Reference in New Issue