jackrabbitを使用するアプリケーションのパフォーマンステストを行った後、私たちは同時に変更するjackrabbitのリポジトリで大きな問題に直面しました。問題は、ノードを追加したり、マルチスレッドエミュレーションで編集したりするときに表示されます。それから私は問題が私たちの環境にないことを私たちに示す非常に簡単なテストを書いた。Jackrabbitと並行変更
ことがあります:
シンプルなステートレスビーン
@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つのスレッドにexecutorを初期化した場合アル私は何のエラーもなしで終わった。我々は試してみました先頭のサーバー上のクライアント
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]
:私は5スレッドにexecutorを初期化した場合、私は時々エラーを得ましたこのメソッドと、マルチスレッド呼び出しを1つのスレッドとして処理するための他のワークフローを同期させます。何も役立ちません。
さらに、私たちがejbレイヤーなしで同様のテストを行ったとき、すべてうまくいきました。 コンテナが自分のトランザクションでラップされているように見え、すべてがクラッシュしました。
多分誰かがこのような問題に直面しました。 ありがとうございます。 Jackrabbit Wikiから
私は常に新しいセッションを行います。 ( )新しいSimpleCredentials( "username"、)は、新しいセッションを開始するために使用されます。 "pwd" .toCharArray())); ' – travmik