tra*_*mik 3 concurrency multithreading jackrabbit
在我们对使用长耳兔的应用程序进行了一些性能测试后,我们遇到了并发修改jackrabbit存储库的巨大问题.当我们在多线程仿真中添加节点或编辑它们时会出现问题.然后我写了一个非常简单的测试,它告诉我们问题不在我们的环境中.
有它:
简单的无状态Bean
@Stateless
@Local(TestFacadeLocal.class)
@Remote(TestFacadeRemote.class)
public class TestFacadeBean implements TestFacadeRemote, TestFacadeLocal {
public void doAction(int name) throws Exception {
new TestSynch().doAction(name);
}
}
简单的课程
public class TestSynch {
public void doAction(int name) throws Exception {
Session session = ((Repository) new InitialContext().
lookup("java:jcr/local")).login(
new SimpleCredentials("username", "pwd".toCharArray()));
List added = new ArrayList();
Node folder = session.getRootNode().getNode("test");
for (int i = 0; i <= 100; i++) {
Node child = folder.addNode("" + System.currentTimeMillis(),
"nt:folder");
child.addMixin("mix:versionable");
added.add(child);
}
// saving butch changes
session.save();
//checking in all created nodes
for (Node node : added) {
session.getWorkspace().getVersionManager().checkin(node.getPath());
}
}
}
和测试课
public class Test {
private int c = 0;
private int countAll = 50;
private ExecutorService executor = Executors.newFixedThreadPool(5);
public ExecutorService getExecutor() {
return executor;
}
public static void main(String[] args) {
Test test = new Test();
try {
test.start();
} catch (Exception e) {
e.printStackTrace();
}
}
private void start() throws Exception {
long time = System.currentTimeMillis();
TestFacadeRemote testBean = (TestFacadeRemote) getContext().
lookup( "test/TestFacadeBean/remote");
for (int i = 0; i < countAll; i++) {
getExecutor().execute(new TestInstallerThread(i, testBean));
}
getExecutor().shutdown();
while (!getExecutor().isTerminated()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(c + " shutdown " +
(System.currentTimeMillis() - time));
}
class TestInstallerThread implements Runnable {
private int number = 0;
TestFacadeRemote testBean;
public TestInstallerThread(int number, TestFacadeRemote testBean) {
this.number = number;
this.testBean = testBean;
}
@Override
public void run() {
try {
System.out.println("Installing data " + number);
testBean.doAction(number);
System.out.println("STOP" + number);
} catch (Exception e) {
e.printStackTrace();
c++;
}
}
}
public Context getContext() throws NamingException {
Properties properties = new Properties();
//init props
..............
return new InitialContext(properties);
}
}
如果我在池中使用1个线程初始化执行程序,则所有操作都没有任何错误.如果我使用5个线程初始化执行程序,我有时会遇到错误:
在客户端
java.lang.RuntimeException: javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] Can't commit because the transaction is in aborted state
at org.jboss.aspects.tx.TxPolicy.handleEndTransactionException(TxPolicy.java:198)
在服务器上开始警告
ItemStateReferenceCache [ItemStateReferenceCache.java:176] overwriting cached entry 187554a7-4c41-404b-b6ee-3ce2a9796a70
然后
javax.jcr.RepositoryException: org.apache.jackrabbit.core.state.ItemStateException: there's already a property state instance with id 52fb4b2c-3ef4-4fc5-9b79-f20a6b2e9ea3/{http://www.jcp.org/jcr/1.0}created
at org.apache.jackrabbit.core.PropertyImpl.restoreTransient(PropertyImpl.java:195) ~[jackrabbit-core-2.2.7.jar:2.2.7]
at org.apache.jackrabbit.core.ItemSaveOperation.restoreTransientItems(ItemSaveOperation.java:879) [jackrabbit-core-2.2.7.jar:2.2.7]
我们已经尝试将此方法和其他工作流同步以处理多线程调用作为一个线程.什么都没有帮助.
还有一件事 - 当我们在没有ejb层的情况下完成类似测试时 - 一切正常.看起来像容器包装在自己的事务中然后全部崩溃.
也许有人面临这样的问题.提前致谢.
小智 5
JCR规范明确声明Session不是线程安全的(JCR 1.0第7.5节和JCR 2.0第4.1.2节).因此,Jackrabbit不支持同时读取或写入同一会话的多个线程.每个会话只能从一个线程访问.
...如果需要同时写入同一节点,则需要使用多个会话,并使用JCR锁定以确保不存在冲突.
| 归档时间: |
|
| 查看次数: |
2891 次 |
| 最近记录: |