More robust concurrency handling of cached references

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2750 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-05-03 23:06:59 +00:00
parent cf4e177ead
commit 56e9002855
2 changed files with 175 additions and 25 deletions

View File

@@ -16,6 +16,10 @@
*/
package org.alfresco.repo.domain.hibernate;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.Node;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -34,10 +38,17 @@ public class ChildAssocImpl implements ChildAssoc
private QName qName;
private boolean isPrimary;
private int index;
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient ChildAssociationRef childAssocRef;
public ChildAssocImpl()
{
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
refReadLock = lock.readLock();
refWriteLock = lock.writeLock();
setIndex(Integer.MAX_VALUE); // comes last
}
@@ -64,19 +75,42 @@ public class ChildAssocImpl implements ChildAssoc
this.getChild().getParentAssocs().remove(this);
}
public synchronized ChildAssociationRef getChildAssocRef()
public ChildAssociationRef getChildAssocRef()
{
if (childAssocRef == null)
// first check if it is available
refReadLock.lock();
try
{
childAssocRef = new ChildAssociationRef(
this.typeQName,
getParent().getNodeRef(),
this.qName,
getChild().getNodeRef(),
this.isPrimary,
-1);
if (childAssocRef != null)
{
return childAssocRef;
}
}
finally
{
refReadLock.unlock();
}
// get write lock
refWriteLock.lock();
try
{
// double check
if (childAssocRef == null )
{
childAssocRef = new ChildAssociationRef(
this.typeQName,
getParent().getNodeRef(),
this.qName,
getChild().getNodeRef(),
this.isPrimary,
-1);
}
return childAssocRef;
}
finally
{
refWriteLock.unlock();
}
return childAssocRef;
}
public String toString()
@@ -161,6 +195,7 @@ public class ChildAssocImpl implements ChildAssoc
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setId(Long id)
{
this.id = id;
@@ -176,7 +211,16 @@ public class ChildAssocImpl implements ChildAssoc
*/
private void setParent(Node parentNode)
{
this.parent = parentNode;
refWriteLock.lock();
try
{
this.parent = parentNode;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
public Node getChild()
@@ -189,7 +233,16 @@ public class ChildAssocImpl implements ChildAssoc
*/
private void setChild(Node node)
{
child = node;
refWriteLock.lock();
try
{
child = node;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
public QName getTypeQName()
@@ -199,7 +252,16 @@ public class ChildAssocImpl implements ChildAssoc
public void setTypeQName(QName typeQName)
{
this.typeQName = typeQName;
refWriteLock.lock();
try
{
this.typeQName = typeQName;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
public QName getQname()
@@ -209,7 +271,16 @@ public class ChildAssocImpl implements ChildAssoc
public void setQname(QName qname)
{
this.qName = qname;
refWriteLock.lock();
try
{
this.qName = qname;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
public boolean getIsPrimary()
@@ -219,7 +290,16 @@ public class ChildAssocImpl implements ChildAssoc
public void setIsPrimary(boolean isPrimary)
{
this.isPrimary = isPrimary;
refWriteLock.lock();
try
{
this.isPrimary = isPrimary;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
public int getIndex()
@@ -229,6 +309,15 @@ public class ChildAssocImpl implements ChildAssoc
public void setIndex(int index)
{
this.index = index;
refWriteLock.lock();
try
{
this.index = index;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
}

View File

@@ -16,6 +16,10 @@
*/
package org.alfresco.repo.domain.hibernate;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodeAssoc;
import org.alfresco.service.cmr.repository.AssociationRef;
@@ -33,10 +37,16 @@ public class NodeAssocImpl implements NodeAssoc
private Node source;
private Node target;
private QName typeQName;
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient AssociationRef nodeAssocRef;
public NodeAssocImpl()
{
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
refReadLock = lock.readLock();
refWriteLock = lock.writeLock();
}
public void buildAssociation(Node sourceNode, Node targetNode)
@@ -62,15 +72,39 @@ public class NodeAssocImpl implements NodeAssoc
this.getTarget().getSourceNodeAssocs().remove(this);
}
public synchronized AssociationRef getNodeAssocRef()
public AssociationRef getNodeAssocRef()
{
if (nodeAssocRef == null)
// first check if it is available
refReadLock.lock();
try
{
nodeAssocRef = new AssociationRef(getSource().getNodeRef(),
this.typeQName,
getTarget().getNodeRef());
if (nodeAssocRef != null)
{
return nodeAssocRef;
}
}
finally
{
refReadLock.unlock();
}
// get write lock
refWriteLock.lock();
try
{
// double check
if (nodeAssocRef == null )
{
nodeAssocRef = new AssociationRef(
getSource().getNodeRef(),
this.typeQName,
getTarget().getNodeRef());
}
return nodeAssocRef;
}
finally
{
refWriteLock.unlock();
}
return nodeAssocRef;
}
public String toString()
@@ -133,7 +167,16 @@ public class NodeAssocImpl implements NodeAssoc
*/
private void setSource(Node source)
{
this.source = source;
refWriteLock.lock();
try
{
this.source = source;
this.nodeAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
public Node getTarget()
@@ -146,7 +189,16 @@ public class NodeAssocImpl implements NodeAssoc
*/
private void setTarget(Node target)
{
this.target = target;
refWriteLock.lock();
try
{
this.target = target;
this.nodeAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
public QName getTypeQName()
@@ -156,6 +208,15 @@ public class NodeAssocImpl implements NodeAssoc
public void setTypeQName(QName typeQName)
{
this.typeQName = typeQName;
refWriteLock.lock();
try
{
this.typeQName = typeQName;
this.nodeAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
}
}