在对使用jackrabbit的应用程序进行了性能测试之后,我们面临着并发修改jackrabbit存储库的巨大问题。当我们添加节点或在多线程仿真中对其进行编辑时,会出现问题。然后,我编写了一个非常简单的测试,向我们表明问题不在我们的环境中。

有:

简单的无状态 bean

@无状态
@Local(TestFacadeLocal.class)
@Remote(TestFacadeRemote.class)
公共(public)类TestFacadeBean实现TestFacadeRemote,TestFacadeLocal {
public void doAction(int name)引发异常{
新的TestSynch()。doAction(name);
}
}

简单课

公共(public)类TestSynch {
public void doAction(int name)引发异常{
session session =((存储库)新的InitialContext()。
lookup(“java:jcr/local”))。login(
新的SimpleCredentials(“username”,“pwd” .toCharArray()));
添加的列表=新的ArrayList();
节点文件夹= session.getRootNode()。getNode(“test”);
对于(int i = 0; i 节点子节点= folder.addNode(“” + System.currentTimeMillis(),
“nt:folder”);
child.addMixin(“mix:versionable”);

add.add(child);
}
//保存Butch更改
session.save();

// checkin 所有创建的节点
对于(节点节点:已添加){
session.getWorkspace()。getVersionManager()。checkin(node.getPath());
}
}
}

和测试类

公开课测试{
private int c = 0;
private int countAll = 50;
私有(private)ExecutorService执行程序= Executors.newFixedThreadPool(5);

public ExecutorService getExecutor(){
退还执行人;
}

公共(public)静态void main(String [] args){
测试测试= new Test();
尝试 {
test.start();
} catch(Exception e){
e.printStackTrace();
}
}

private void start()引发异常{
很长的时间= System.currentTimeMillis();
TestFacadeRemote testBean =(TestFacadeRemote)getContext()。
lookup(“test/TestFacadeBean/remote”);
for(int i = 0; i getExecutor()。execute(new TestInstallerThread(i,testBean));
}

getExecutor()。shutdown();
while(!getExecutor()。isTerminated()){
尝试 {
Thread.sleep(500);
} catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println(c +“关闭” +
(System.currentTimeMillis()-时间));

}

TestInstallerThread类实现Runnable {
private int数字= 0;
TestFacadeRemote testBean;

public TestInstallerThread(int number,TestFacadeRemote testBean){
this.number =数字;
this.testBean = testBean;
}

@Override
公共(public)无效run(){
尝试 {
System.out.println(“正在安装数据” +号);
testBean.doAction(number);
System.out.println(“STOP” +数字);
} catch(Exception e){
e.printStackTrace();
c++;
}
}

}

公共(public)上下文getContext()抛出NamingException {
属性properties = new Properties();
//初始化 Prop
..............
返回新的InitialContext(properties);
}
}

如果我用池中的1个线程初始化了executor,那么所有操作都完成了而没有任何错误。如果我用5个线程初始化执行程序,有时会出错:

在客户端上

java.lang.RuntimeException:javax.transaction.RollbackException:[com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted]无法提交因为事务处于中止状态
在org.jboss.aspects.tx.TxPolicy.handleEndTransactionException(TxPolicy.java:198)

开始时在服务器上发出警告

ItemStateReferenceCache [ItemStateReferenceCache.java:176]覆盖缓存的条目187554a7-4c41-404b-b6ee-3ce2a9796a70

接着

javax.jcr.RepositoryException:org.apache.jackrabbit.core.state.ItemStateException:已经存在一个ID为52fb4b2c-3ef4-4fc5-9b79-f20a6b2e9ea3/{http://www.jcp.org/jcr/1.0的属性状态实例}创建
在org.apache.jackrabbit.core.PropertyImpl.restoreTransient(PropertyImpl.java:195)〜[jackrabbit-core-2.2.7.jar:2.2.7]
在org.apache.jackrabbit.core.ItemSaveOperation.restoreTransientItems(ItemSaveOperation.java:879)[jackrabbit-core-2.2.7.jar:2.2.7]

我们尝试同步此方法和其他工作流程,以将多线程调用作为一个线程处理。没有任何帮助。

还有一件事-当我们在没有ejb层的情况下进行了类似的测试时-一切正常。
看起来容器包装在自己的事务中,然后全部崩溃了。

也许有人面临这样的问题。
提前致谢。

最佳答案

Jackrabbit Wiki:

关于multithreading - Jackrabbit和并发修改,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6680237/

10-14 11:55