gpt4 book ai didi

multithreading - Jackrabbit 和并发修改

转载 作者:行者123 更新时间:2023-12-01 23:43:29 34 4
gpt4 key购买 nike

在我们对使用 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 层的情况下进行类似的测试时 - 一切都工作正常。看起来就像容器包装在自己的事务中,然后全部崩溃。

也许有人遇到过这样的问题。提前致谢。

最佳答案

来自Jackrabbit Wiki :

The JCR specification explicitly states that a Session is not thread-safe (JCR 1.0 section 7.5 and JCR 2.0 section 4.1.2). Hence, Jackrabbit does not support multiple threads concurrently reading from or writing to the same session. Each session should only ever be accessed from one thread.

...If you need to write to the same node concurrently, then you need to use multiple sessions, and use JCR locking to ensure there is no conflict.

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

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com