Introduced lock functionality to ConcurrentModificationCheckConcern to prevent simultaneous updates of the same entity.
Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/4da4e221 Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/4da4e221 Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/4da4e221 Branch: refs/heads/master Commit: 4da4e22133f687b439413e4a70e56f963a4cf2ff Parents: 5b513e0 Author: Arvid Huss <[email protected]> Authored: Mon Mar 11 07:29:33 2013 +0100 Committer: Arvid Huss <[email protected]> Committed: Mon Mar 11 07:29:33 2013 +0100 ---------------------------------------------------------------------- .../ConcurrentModificationCheckConcern.java | 40 ++++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/4da4e221/core/spi/src/main/java/org/qi4j/spi/entitystore/ConcurrentModificationCheckConcern.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/qi4j/spi/entitystore/ConcurrentModificationCheckConcern.java b/core/spi/src/main/java/org/qi4j/spi/entitystore/ConcurrentModificationCheckConcern.java index 3193baa..f6599f5 100644 --- a/core/spi/src/main/java/org/qi4j/spi/entitystore/ConcurrentModificationCheckConcern.java +++ b/core/spi/src/main/java/org/qi4j/spi/entitystore/ConcurrentModificationCheckConcern.java @@ -14,8 +14,6 @@ package org.qi4j.spi.entitystore; -import java.util.ArrayList; -import java.util.List; import org.qi4j.api.Qi4j; import org.qi4j.api.concern.ConcernOf; import org.qi4j.api.entity.EntityDescriptor; @@ -26,6 +24,10 @@ import org.qi4j.api.structure.Module; import org.qi4j.api.usecase.Usecase; import org.qi4j.spi.entity.EntityState; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.ReentrantReadWriteLock; + /** * Concern that helps EntityStores do concurrent modification checks. * <p/> @@ -61,6 +63,8 @@ public abstract class ConcurrentModificationCheckConcern private List<EntityState> loaded = new ArrayList<EntityState>(); + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock( ); + public ConcurrentCheckingEntityStoreUnitOfWork( EntityStoreUnitOfWork uow, EntityStateVersions versions, Module module, @@ -96,6 +100,8 @@ public abstract class ConcurrentModificationCheckConcern public StateCommitter applyChanges() throws EntityStoreException { + lock.writeLock().lock(); + versions.checkForConcurrentModification( loaded, module, currentTime ); final StateCommitter committer = uow.applyChanges(); @@ -107,6 +113,8 @@ public abstract class ConcurrentModificationCheckConcern { committer.commit(); versions.forgetVersions( loaded ); + + lock.writeLock().unlock(); } @Override @@ -114,6 +122,8 @@ public abstract class ConcurrentModificationCheckConcern { committer.cancel(); versions.forgetVersions( loaded ); + + lock.writeLock().unlock(); } }; } @@ -127,7 +137,15 @@ public abstract class ConcurrentModificationCheckConcern } finally { - versions.forgetVersions( loaded ); + lock.writeLock().lock(); + + try + { + versions.forgetVersions( loaded ); + } finally + { + lock.writeLock().unlock(); + } } } @@ -135,10 +153,18 @@ public abstract class ConcurrentModificationCheckConcern public EntityState entityStateOf( EntityReference anIdentity ) throws EntityStoreException, EntityNotFoundException { - EntityState entityState = uow.entityStateOf( anIdentity ); - versions.rememberVersion( entityState.identity(), entityState.version() ); - loaded.add( entityState ); - return entityState; + lock.readLock().lock(); + + try + { + EntityState entityState = uow.entityStateOf( anIdentity ); + versions.rememberVersion( entityState.identity(), entityState.version() ); + loaded.add( entityState ); + return entityState; + } finally + { + lock.readLock().unlock(); + } } } }
