Après avoir fait quelques tests de performance pour notre application qui utilise jackrabbit, nous avons dû faire face à l'énorme problème avec le référentiel de modification simultanée de jackrabbit. Le problème apparaît lorsque nous ajoutons des nœuds ou que nous les éditons dans une émulation multithread. Puis j'ai écrit un test très simple qui nous montre que le problème n'est pas dans notre environnement.Jackrabbit et modification simultanée
Il est-il:
Simple Stateless 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); } }
classe simple
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()); } } }
et classe Test
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); } }
Si j'initialisés exécuteur avec 1 fil dans la piscine Al Je l'ai fait sans aucune erreur. Si j'initialisés exécuteur avec 5 fils, je suis parfois des erreurs:
sur le client
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)
sur le serveur au début avertir
ItemStateReferenceCache [ItemStateReferenceCache.java:176] overwriting cached entry 187554a7-4c41-404b-b6ee-3ce2a9796a70
puis
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]
Nous avons essayé synchroniser cette méthode et un autre flux de travail pour gérer les appels multithread comme un seul thread. Rien ne aide.
Et encore une chose - lorsque nous avons fait un test similaire sans couche ejb - tout a bien fonctionné. Il ressemble à un conteneur enveloppé dans sa propre transaction, puis tout s'est écrasé.
Peut-être que quelqu'un a été confronté à un tel problème. Merci d'avance.
Et je fais toujours une nouvelle session. 'nouveau TestSynch() doAction (nom)' 'session de session =. ((Dépôt) new InitialContext() de recherche (. "Java: JCR/local")). Login ( nouvelles SimpleCredentials ("nom d'utilisateur", "pwd" .toCharArray())) – travmik