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; 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.ChildAssoc;
import org.alfresco.repo.domain.Node; import org.alfresco.repo.domain.Node;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -34,10 +38,17 @@ public class ChildAssocImpl implements ChildAssoc
private QName qName; private QName qName;
private boolean isPrimary; private boolean isPrimary;
private int index; private int index;
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient ChildAssociationRef childAssocRef; private transient ChildAssociationRef childAssocRef;
public ChildAssocImpl() public ChildAssocImpl()
{ {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
refReadLock = lock.readLock();
refWriteLock = lock.writeLock();
setIndex(Integer.MAX_VALUE); // comes last setIndex(Integer.MAX_VALUE); // comes last
} }
@@ -64,19 +75,42 @@ public class ChildAssocImpl implements ChildAssoc
this.getChild().getParentAssocs().remove(this); 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( if (childAssocRef != null)
this.typeQName, {
getParent().getNodeRef(), return childAssocRef;
this.qName, }
getChild().getNodeRef(), }
this.isPrimary, finally
-1); {
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() public String toString()
@@ -161,6 +195,7 @@ public class ChildAssocImpl implements ChildAssoc
/** /**
* For Hibernate use * For Hibernate use
*/ */
@SuppressWarnings("unused")
private void setId(Long id) private void setId(Long id)
{ {
this.id = id; this.id = id;
@@ -176,7 +211,16 @@ public class ChildAssocImpl implements ChildAssoc
*/ */
private void setParent(Node parentNode) private void setParent(Node parentNode)
{ {
this.parent = parentNode; refWriteLock.lock();
try
{
this.parent = parentNode;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
public Node getChild() public Node getChild()
@@ -189,7 +233,16 @@ public class ChildAssocImpl implements ChildAssoc
*/ */
private void setChild(Node node) private void setChild(Node node)
{ {
child = node; refWriteLock.lock();
try
{
child = node;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
public QName getTypeQName() public QName getTypeQName()
@@ -199,7 +252,16 @@ public class ChildAssocImpl implements ChildAssoc
public void setTypeQName(QName typeQName) public void setTypeQName(QName typeQName)
{ {
this.typeQName = typeQName; refWriteLock.lock();
try
{
this.typeQName = typeQName;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
public QName getQname() public QName getQname()
@@ -209,7 +271,16 @@ public class ChildAssocImpl implements ChildAssoc
public void setQname(QName qname) public void setQname(QName qname)
{ {
this.qName = qname; refWriteLock.lock();
try
{
this.qName = qname;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
public boolean getIsPrimary() public boolean getIsPrimary()
@@ -219,7 +290,16 @@ public class ChildAssocImpl implements ChildAssoc
public void setIsPrimary(boolean isPrimary) public void setIsPrimary(boolean isPrimary)
{ {
this.isPrimary = isPrimary; refWriteLock.lock();
try
{
this.isPrimary = isPrimary;
this.childAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
public int getIndex() public int getIndex()
@@ -229,6 +309,15 @@ public class ChildAssocImpl implements ChildAssoc
public void setIndex(int index) 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; 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.Node;
import org.alfresco.repo.domain.NodeAssoc; import org.alfresco.repo.domain.NodeAssoc;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.AssociationRef;
@@ -33,10 +37,16 @@ public class NodeAssocImpl implements NodeAssoc
private Node source; private Node source;
private Node target; private Node target;
private QName typeQName; private QName typeQName;
private transient ReadLock refReadLock;
private transient WriteLock refWriteLock;
private transient AssociationRef nodeAssocRef; private transient AssociationRef nodeAssocRef;
public NodeAssocImpl() public NodeAssocImpl()
{ {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
refReadLock = lock.readLock();
refWriteLock = lock.writeLock();
} }
public void buildAssociation(Node sourceNode, Node targetNode) public void buildAssociation(Node sourceNode, Node targetNode)
@@ -62,15 +72,39 @@ public class NodeAssocImpl implements NodeAssoc
this.getTarget().getSourceNodeAssocs().remove(this); 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(), if (nodeAssocRef != null)
this.typeQName, {
getTarget().getNodeRef()); 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() public String toString()
@@ -133,7 +167,16 @@ public class NodeAssocImpl implements NodeAssoc
*/ */
private void setSource(Node source) private void setSource(Node source)
{ {
this.source = source; refWriteLock.lock();
try
{
this.source = source;
this.nodeAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
public Node getTarget() public Node getTarget()
@@ -146,7 +189,16 @@ public class NodeAssocImpl implements NodeAssoc
*/ */
private void setTarget(Node target) private void setTarget(Node target)
{ {
this.target = target; refWriteLock.lock();
try
{
this.target = target;
this.nodeAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
public QName getTypeQName() public QName getTypeQName()
@@ -156,6 +208,15 @@ public class NodeAssocImpl implements NodeAssoc
public void setTypeQName(QName typeQName) public void setTypeQName(QName typeQName)
{ {
this.typeQName = typeQName; refWriteLock.lock();
try
{
this.typeQName = typeQName;
this.nodeAssocRef = null;
}
finally
{
refWriteLock.unlock();
}
} }
} }