mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-02 17:35:18 +00:00
Added pessimistic locking in several places to shut down deadlocks.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3252 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
64288d531d
commit
c6dfeb1c9d
@ -35,7 +35,7 @@ public class AVMStressTest extends AVMServiceTestBase
|
||||
{
|
||||
try
|
||||
{
|
||||
int nCopies = 1;
|
||||
int nCopies = 4;
|
||||
int nThreads = 8;
|
||||
BulkLoader loader = new BulkLoader(fService);
|
||||
long start = System.currentTimeMillis();
|
||||
@ -60,7 +60,7 @@ public class AVMStressTest extends AVMServiceTestBase
|
||||
20, // modify file.
|
||||
3200, // read file
|
||||
10, // snapshot
|
||||
10000, // # ops
|
||||
1000, // # ops
|
||||
fService,
|
||||
"" + i);
|
||||
tester.refresh();
|
||||
@ -73,6 +73,7 @@ public class AVMStressTest extends AVMServiceTestBase
|
||||
thread.start();
|
||||
}
|
||||
int exited = 0;
|
||||
long sampStart = System.currentTimeMillis();
|
||||
while (exited != nThreads)
|
||||
{
|
||||
try
|
||||
@ -99,6 +100,22 @@ public class AVMStressTest extends AVMServiceTestBase
|
||||
exited++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
long now = System.currentTimeMillis();
|
||||
if (now - sampStart > 30000)
|
||||
{
|
||||
System.err.println("RATE: " + (((long)AVMTester.GetCount()) * 1000 / (now - sampStart)));
|
||||
for (AVMTester tester : testers)
|
||||
{
|
||||
tester.setExit();
|
||||
}
|
||||
for (Thread thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
fail();
|
||||
}
|
||||
*/
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
|
@ -51,6 +51,7 @@ class AVMTester implements Runnable
|
||||
private List<String> fAllFiles;
|
||||
|
||||
private static boolean fgFrozen = false;
|
||||
private static int fgOpCount = 0;
|
||||
|
||||
/**
|
||||
* The operation table.
|
||||
@ -239,6 +240,7 @@ class AVMTester implements Runnable
|
||||
snapshot();
|
||||
break;
|
||||
}
|
||||
IncCount();
|
||||
}
|
||||
System.out.println(fAllPaths.size() + " fses in " + (System.currentTimeMillis() - startTime) +
|
||||
"ms");
|
||||
@ -615,4 +617,14 @@ class AVMTester implements Runnable
|
||||
{
|
||||
return fAllPaths.get(fgRandom.nextInt(fAllPaths.size()));
|
||||
}
|
||||
|
||||
private static synchronized void IncCount()
|
||||
{
|
||||
++fgOpCount;
|
||||
}
|
||||
|
||||
public static synchronized int GetCount()
|
||||
{
|
||||
return fgOpCount;
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,9 @@ interface DirectoryNode extends AVMNode
|
||||
* @param lPath The Lookup so far.
|
||||
* @param name The name of the child to lookup.
|
||||
* @param version The version to look under.
|
||||
* @param visited A Set of full paths visited. Used for cycle checking.
|
||||
* @param write Whether this is occuring in a write context.
|
||||
*/
|
||||
public AVMNode lookupChild(Lookup lPath, String name, int version);
|
||||
public AVMNode lookupChild(Lookup lPath, String name, int version, boolean write);
|
||||
|
||||
/**
|
||||
* Lookup a child node using an AVMNodeDescriptor as context.
|
||||
|
@ -19,6 +19,7 @@ package org.alfresco.repo.avm;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
|
||||
@ -49,13 +50,16 @@ abstract class DirectoryNodeImpl extends AVMNodeImpl implements DirectoryNode
|
||||
/**
|
||||
* Retrieves the ChildEntry in this directory with the given name.
|
||||
* @param name The name to look for.
|
||||
* @param write Whether the child should be looked up for writing.
|
||||
* @return The ChildEntry or null if not found.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ChildEntry getChild(String name)
|
||||
protected ChildEntry getChild(String name, boolean write)
|
||||
{
|
||||
Session sess = SuperRepository.GetInstance().getSession();
|
||||
return (ChildEntry)sess.get(ChildEntryImpl.class, new ChildEntryImpl(name, this, null));
|
||||
ChildEntry entry = (ChildEntry)sess.get(ChildEntryImpl.class, new ChildEntryImpl(name, this, null),
|
||||
(write && getIsNew()) ? LockMode.UPGRADE : LockMode.READ);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -381,17 +381,18 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
|
||||
* @param lPath The Lookup.
|
||||
* @param name The name we are looking.
|
||||
* @param version The version in which we are looking.
|
||||
* @param write Whether this lookup is occurring in a write context.
|
||||
* @return The child or null if not found.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public AVMNode lookupChild(Lookup lPath, String name, int version)
|
||||
public AVMNode lookupChild(Lookup lPath, String name, int version, boolean write)
|
||||
{
|
||||
// If the name has been deleted quickly return.
|
||||
if (getDeleted(name) != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ChildEntry entry = getChild(name);
|
||||
ChildEntry entry = getChild(name, write);
|
||||
if (entry != null)
|
||||
{
|
||||
return AVMNodeUnwrapper.Unwrap(entry.getChild());
|
||||
@ -401,7 +402,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
|
||||
{
|
||||
Lookup lookup = SuperRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
|
||||
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
|
||||
return dir.lookupChild(lookup, name, -1);
|
||||
return dir.lookupChild(lookup, name, -1, false);
|
||||
}
|
||||
catch (AVMException re)
|
||||
{
|
||||
@ -429,7 +430,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ChildEntry entry = getChild(name);
|
||||
ChildEntry entry = getChild(name, false);
|
||||
if (entry != null)
|
||||
{
|
||||
return entry.getChild().getDescriptor(mine.getPath(),
|
||||
@ -440,7 +441,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
|
||||
{
|
||||
Lookup lookup = SuperRepository.GetInstance().lookupDirectory(-1, mine.getIndirection());
|
||||
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
|
||||
AVMNode child = dir.lookupChild(lookup, name, -1);
|
||||
AVMNode child = dir.lookupChild(lookup, name, -1, false);
|
||||
if (child == null)
|
||||
{
|
||||
return null;
|
||||
@ -464,7 +465,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
|
||||
@SuppressWarnings("unchecked")
|
||||
public void removeChild(String name)
|
||||
{
|
||||
ChildEntry entry = getChild(name);
|
||||
ChildEntry entry = getChild(name, true);
|
||||
if (entry != null)
|
||||
{
|
||||
SuperRepository.GetInstance().getSession().delete(entry);
|
||||
|
@ -126,14 +126,15 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
|
||||
* @param lPath The lookup path so far.
|
||||
* @param name The name to lookup.
|
||||
* @param version The version to look under.
|
||||
* @param write Whether this is in a write context.
|
||||
* @return The child or null.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public AVMNode lookupChild(Lookup lPath, String name, int version)
|
||||
public AVMNode lookupChild(Lookup lPath, String name, int version, boolean write)
|
||||
{
|
||||
// We're doing the hand unrolling of the proxy because
|
||||
// Hibernate/CGLIB proxies are broken.
|
||||
ChildEntry entry = getChild(name);
|
||||
ChildEntry entry = getChild(name, write);
|
||||
if (entry == null)
|
||||
{
|
||||
return null;
|
||||
@ -153,7 +154,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
|
||||
{
|
||||
throw new AVMBadArgumentException("Path is null.");
|
||||
}
|
||||
ChildEntry entry = getChild(name);
|
||||
ChildEntry entry = getChild(name, false);
|
||||
if (entry == null)
|
||||
{
|
||||
return null;
|
||||
@ -168,7 +169,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
|
||||
@SuppressWarnings("unchecked")
|
||||
public void removeChild(String name)
|
||||
{
|
||||
ChildEntry entry = getChild(name);
|
||||
ChildEntry entry = getChild(name, true);
|
||||
if (entry != null)
|
||||
{
|
||||
SuperRepository.GetInstance().getSession().delete(entry);
|
||||
|
@ -162,7 +162,7 @@ class RepositoryImpl implements Repository, Serializable
|
||||
Lookup lPath = lookupDirectory(-1, path, true);
|
||||
// lPath.acquireLocks();
|
||||
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
|
||||
if (dir.lookupChild(lPath, name, -1) != null)
|
||||
if (dir.lookupChild(lPath, name, -1, true) != null)
|
||||
{
|
||||
throw new AVMExistsException("Child exists: " + name);
|
||||
}
|
||||
@ -195,7 +195,7 @@ class RepositoryImpl implements Repository, Serializable
|
||||
Lookup lPath = lookupDirectory(-1, dstPath, true);
|
||||
// lPath.acquireLocks();
|
||||
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
|
||||
if (dir.lookupChild(lPath, name, -1) != null)
|
||||
if (dir.lookupChild(lPath, name, -1, true) != null)
|
||||
{
|
||||
throw new AVMExistsException("Child exists: " + name);
|
||||
}
|
||||
@ -230,7 +230,7 @@ class RepositoryImpl implements Repository, Serializable
|
||||
Lookup lPath = lookupDirectory(-1, path, true);
|
||||
// lPath.acquireLocks();
|
||||
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
|
||||
if (dir.lookupChild(lPath, name, -1) != null)
|
||||
if (dir.lookupChild(lPath, name, -1, true) != null)
|
||||
{
|
||||
throw new AVMExistsException("Child exists: " + name);
|
||||
}
|
||||
@ -251,7 +251,7 @@ class RepositoryImpl implements Repository, Serializable
|
||||
Lookup lPath = lookupDirectory(-1, dstPath, true);
|
||||
// lPath.acquireLocks();
|
||||
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
|
||||
if (dir.lookupChild(lPath, name, -1) != null)
|
||||
if (dir.lookupChild(lPath, name, -1, true) != null)
|
||||
{
|
||||
throw new AVMExistsException("Child exists: " + name);
|
||||
}
|
||||
@ -372,7 +372,7 @@ class RepositoryImpl implements Repository, Serializable
|
||||
Lookup lPath = lookupDirectory(-1, path, true);
|
||||
// lPath.acquireLocks();
|
||||
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
|
||||
if (dir.lookupChild(lPath, name, -1) == null)
|
||||
if (dir.lookupChild(lPath, name, -1, true) == null)
|
||||
{
|
||||
throw new AVMNotFoundException("Does not exist: " + name);
|
||||
}
|
||||
@ -528,7 +528,7 @@ class RepositoryImpl implements Repository, Serializable
|
||||
// before the end.
|
||||
for (int i = 0; i < pathElements.length - 1; i++)
|
||||
{
|
||||
AVMNode child = dir.lookupChild(result, pathElements[i], version);
|
||||
AVMNode child = dir.lookupChild(result, pathElements[i], version, write);
|
||||
if (child == null)
|
||||
{
|
||||
throw new AVMNotFoundException("Not found: " + pathElements[i]);
|
||||
@ -544,7 +544,7 @@ class RepositoryImpl implements Repository, Serializable
|
||||
dir = (DirectoryNode)result.getCurrentNode();
|
||||
}
|
||||
// Now look up the last element.
|
||||
AVMNode child = dir.lookupChild(result, pathElements[pathElements.length - 1], version);
|
||||
AVMNode child = dir.lookupChild(result, pathElements[pathElements.length - 1], version, write);
|
||||
if (child == null)
|
||||
{
|
||||
throw new AVMNotFoundException("Not found: " + pathElements[pathElements.length - 1]);
|
||||
|
@ -32,8 +32,8 @@ public class SimultaneousLoadTest extends AVMServiceTestBase
|
||||
{
|
||||
try
|
||||
{
|
||||
int n = 8;
|
||||
int m = 1;
|
||||
int n = 1;
|
||||
int m = 8;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
fService.createDirectory("main:/", "d" + i);
|
||||
@ -42,7 +42,7 @@ public class SimultaneousLoadTest extends AVMServiceTestBase
|
||||
Thread [] threads = new Thread[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
Loader loader = new Loader("/Users/britt/stuff/" + i, "main:/d" + i, m);
|
||||
Loader loader = new Loader("source", "main:/d" + i, m);
|
||||
threads[i] = new Thread(loader);
|
||||
threads[i].start();
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ class SuperRepository
|
||||
Lookup sPath = srcRepo.lookupDirectory(-1, pathParts[1], true);
|
||||
// sPath.acquireLocks();
|
||||
DirectoryNode srcDir = (DirectoryNode)sPath.getCurrentNode();
|
||||
AVMNode srcNode = srcDir.lookupChild(sPath, srcName, -1);
|
||||
AVMNode srcNode = srcDir.lookupChild(sPath, srcName, -1, true);
|
||||
if (srcNode == null)
|
||||
{
|
||||
throw new AVMNotFoundException("Not found: " + srcName);
|
||||
@ -310,7 +310,7 @@ class SuperRepository
|
||||
Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true);
|
||||
// dPath.acquireLocks();
|
||||
DirectoryNode dstDir = (DirectoryNode)dPath.getCurrentNode();
|
||||
AVMNode dstNode = dstDir.lookupChild(dPath, dstName, -1);
|
||||
AVMNode dstNode = dstDir.lookupChild(dPath, dstName, -1, true);
|
||||
if (dstNode != null)
|
||||
{
|
||||
throw new AVMExistsException("Node exists: " + dstName);
|
||||
@ -422,6 +422,7 @@ class SuperRepository
|
||||
for (String repName : repositories)
|
||||
{
|
||||
Repository repo = getRepositoryByName(repName, true);
|
||||
fSession.get().lock(repo, LockMode.UPGRADE);
|
||||
// fSession.get().lock(repo, LockMode.UPGRADE);
|
||||
repo.createSnapshot();
|
||||
}
|
||||
@ -434,6 +435,7 @@ class SuperRepository
|
||||
public void createSnapshot(String repository)
|
||||
{
|
||||
Repository repo = getRepositoryByName(repository, true);
|
||||
fSession.get().lock(repo, LockMode.UPGRADE);
|
||||
// fSession.get().lock(repo, LockMode.UPGRADE);
|
||||
repo.createSnapshot();
|
||||
}
|
||||
@ -694,12 +696,16 @@ class SuperRepository
|
||||
private Repository getRepositoryByName(String name, boolean write)
|
||||
{
|
||||
Repository rep = (Repository)fSession.get().get(RepositoryImpl.class,
|
||||
name /* ,
|
||||
name, LockMode.READ /*,
|
||||
write ? LockMode.UPGRADE : LockMode.READ*/);
|
||||
if (rep == null)
|
||||
{
|
||||
throw new AVMNotFoundException("Repository not found: " + name);
|
||||
}
|
||||
if (write && !rep.getRoot().getIsNew())
|
||||
{
|
||||
fSession.get().lock(rep, LockMode.UPGRADE);
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ public class HibernateTxn
|
||||
}
|
||||
*/
|
||||
sess = fSessionFactory.openSession();
|
||||
sess.setFlushMode(FlushMode.ALWAYS);
|
||||
// sess.setFlushMode(FlushMode.ALWAYS);
|
||||
txn = sess.beginTransaction();
|
||||
callback.perform(sess);
|
||||
txn.commit();
|
||||
|
Loading…
x
Reference in New Issue
Block a user