Jackrabbit 和并发修改
Posted
技术标签:
【中文标题】Jackrabbit 和并发修改【英文标题】:Jackrabbit and concurrent modification 【发布时间】:2011-10-04 13:06:57 【问题描述】:在我们对使用 jackrabbit 的应用程序进行了一些性能测试后,我们面临着并发修改 jackrabbit 存储库的巨大问题。当我们在多线程仿真中添加节点或编辑它们时会出现问题。然后我写了一个非常简单的测试,告诉我们问题不在我们的环境中。
就是这样:
简单的无状态 Bean
@无状态 @Local(TestFacadeLocal.class) @Remote(TestFacadeRemote.class) 公共类 TestFacadeBean 实现 TestFacadeRemote,TestFacadeLocal 公共无效doAction(int name)抛出异常 新的 TestSynch().doAction(name);简单类
公共类TestSynch 公共无效doAction(int name)抛出异常 会话 session = ((Repository) new InitialContext(). 查找("java:jcr/local")).login( new SimpleCredentials("username", "pwd".toCharArray())); 添加列表 = new ArrayList(); 节点文件夹 = session.getRootNode().getNode("test"); for (int i = 0; i和测试类
公共类测试 私人int c = 0; 私人int countAll = 50; private ExecutorService executor = Executors.newFixedThreadPool(5); 公共 ExecutorService getExecutor() 返回执行人; 公共静态无效主要(字符串[]参数) 测试 test = new Test(); 尝试 test.start(); 捕捉(异常 e) e.printStackTrace(); 私人无效开始()抛出异常 长时间 = System.currentTimeMillis(); TestFacadeRemote testBean = (TestFacadeRemote) getContext(). 查找(“测试/TestFacadeBean/远程”); for (int i = 0; i如果我用池中的 1 个线程初始化执行程序,所有这些都没有任何错误。如果我用 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 层的情况下进行了类似的测试时——一切正常。 它看起来像容器包装在自己的事务中,然后全部崩溃。
也许有人遇到过这样的问题。 提前致谢。
【问题讨论】:
【参考方案1】:来自Jackrabbit Wiki:
JCR 规范明确声明会话不是线程安全的(JCR 1.0 第 7.5 节和 JCR 2.0 第 4.1.2 节)。因此,Jackrabbit 不支持多个线程同时读取或写入同一会话。每个会话只能从一个线程访问。
... 如果需要同时写入同一个节点,那么就需要使用多个会话,并使用JCR锁来保证不冲突。
【讨论】:
我总是新的会话。new TestSynch().doAction(name)
Session session = ((Repository) new InitialContext(). lookup("java:jcr/local")).login( new SimpleCredentials("username", "pwd".toCharArray()));
以上是关于Jackrabbit 和并发修改的主要内容,如果未能解决你的问题,请参考以下文章