use of org.hibernate.cache.spi.access.SoftLock in project hibernate-orm by hibernate.
the class ReadWriteNaturalIdRegionAccessStrategy method afterUpdate.
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
try {
writeLock.lock();
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isUnlockable(lock)) {
Lock lockItem = (Lock) item;
if (lockItem.wasLockedConcurrently()) {
decrementLock(session, key, lockItem);
return false;
} else {
region.put(session, key, new Item(value, null, region.nextTimestamp()));
return true;
}
} else {
handleLockExpiry(session, key, item);
return false;
}
} finally {
writeLock.unlock();
}
}
use of org.hibernate.cache.spi.access.SoftLock in project hibernate-orm by hibernate.
the class HibernateCacheTest method testStaleWritesLeaveCacheConsistent.
@Test
public void testStaleWritesLeaveCacheConsistent() {
Session s = sessionFactory().openSession();
Transaction txn = s.beginTransaction();
VersionedItem item = new VersionedItem();
item.setName("steve");
item.setDescription("steve's item");
s.save(item);
txn.commit();
s.close();
Long initialVersion = item.getVersion();
// manually revert the version property
item.setVersion(item.getVersion() - 1);
try {
s = sessionFactory().openSession();
txn = s.beginTransaction();
s.update(item);
txn.commit();
s.close();
fail("expected stale write to fail");
} catch (Throwable expected) {
// expected behavior here
if (txn != null) {
try {
txn.rollback();
} catch (Throwable ignore) {
}
}
} finally {
if (s != null && s.isOpen()) {
try {
s.close();
} catch (Throwable ignore) {
}
}
}
// check the version value in the cache...
SecondLevelCacheStatistics slcs = sessionFactory().getStatistics().getSecondLevelCacheStatistics(REGION_PREFIX + VersionedItem.class.getName());
assertNotNull(slcs);
final Map entries = slcs.getEntries();
Object entry = entries.get(item.getId());
Long cachedVersionValue;
if (entry instanceof SoftLock) {
//FIXME don't know what to test here
//cachedVersionValue = new Long( ( (ReadWriteCache.Lock) entry).getUnlockTimestamp() );
} else {
cachedVersionValue = (Long) ((Map) entry).get("_version");
assertThat(initialVersion, equalTo(cachedVersionValue));
}
// cleanup
s = sessionFactory().openSession();
txn = s.beginTransaction();
item = (VersionedItem) s.load(VersionedItem.class, item.getId());
s.delete(item);
txn.commit();
s.close();
}
use of org.hibernate.cache.spi.access.SoftLock in project hibernate-orm by hibernate.
the class DefaultLoadEventListener method lockAndLoad.
/**
* If the class to be loaded has been configured with a cache, then lock
* given id in that cache and then perform the load.
*
* @param event The initiating load request event
* @param persister The persister corresponding to the entity to be loaded
* @param keyToLoad The key of the entity to be loaded
* @param options The defined load options
* @param source The originating session
*
* @return The loaded entity
*
* @throws HibernateException
*/
private Object lockAndLoad(final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final SessionImplementor source) {
SoftLock lock = null;
final Object ck;
final EntityDataAccess cache = persister.getCacheAccessStrategy();
if (persister.canWriteToCache()) {
ck = cache.generateCacheKey(event.getEntityId(), persister, source.getFactory(), source.getTenantIdentifier());
lock = persister.getCacheAccessStrategy().lockItem(source, ck, null);
} else {
ck = null;
}
Object entity;
try {
entity = load(event, persister, keyToLoad, options);
} finally {
if (persister.canWriteToCache()) {
cache.unlockItem(source, ck, lock);
}
}
return event.getSession().getPersistenceContext().proxyFor(persister, keyToLoad, entity);
}
use of org.hibernate.cache.spi.access.SoftLock in project hibernate-orm by hibernate.
the class DefaultRefreshEventListener method evictCachedCollections.
private void evictCachedCollections(Type[] types, Serializable id, EventSource source) throws HibernateException {
for (Type type : types) {
if (type.isCollectionType()) {
CollectionPersister collectionPersister = source.getFactory().getMetamodel().collectionPersister(((CollectionType) type).getRole());
if (collectionPersister.hasCache()) {
final CollectionDataAccess cache = collectionPersister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(id, collectionPersister, source.getFactory(), source.getTenantIdentifier());
final SoftLock lock = cache.lockItem(source, ck, null);
cache.remove(source, ck);
source.getActionQueue().registerProcess((success, session) -> cache.unlockItem(session, ck, lock));
}
} else if (type.isComponentType()) {
CompositeType actype = (CompositeType) type;
evictCachedCollections(actype.getSubtypes(), id, source);
}
}
}
use of org.hibernate.cache.spi.access.SoftLock in project hibernate-orm by hibernate.
the class CollectionAction method beforeExecutions.
@Override
public final void beforeExecutions() throws CacheException {
// the database (this action is responsible for second-level cache invalidation only)
if (persister.hasCache()) {
final CollectionDataAccess cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(key, persister, session.getFactory(), session.getTenantIdentifier());
final SoftLock lock = cache.lockItem(session, ck, null);
// the old behavior used key as opposed to getKey()
afterTransactionProcess = new CacheCleanupProcess(key, persister, lock);
}
}
Aggregations