RollbackException:由PlaceboTransaction上的close()而没有success()引起

时间:2014-10-22 22:44:27

标签: spring-data-neo4j

自从我将Neo4j从1.9.8升级到2.1.2。和从3.2.0到3.2.5的Spring-Data,我看到了" RollbackException"当我尝试从事务中调用 TopLevelTransaction.close(..)时。如果线程还没有与之关联的事务,则不会发生这种情况。

  

neo4j.kernel.TopLevelTransaction.close(TopLevelTransaction.java:134)   〜[Neo4j的内核-2.1.2.jar:2.1.2]
  在org.neo4j.kernel.TopLevelTransaction.finish(TopLevelTransaction.java:111)

     

....引起:javax.transaction.RollbackException:提交失败,事务回滚
  at org.neo4j.kernel.impl.transaction.TxManager.rollbackCommit(TxManager.java:629)   在org.neo4j.kernel.impl.transaction.TxManager.commit(TxManager.java:390)   在org.neo4j.kernel.impl.transaction.TransactionImpl.commit(TransactionImpl.java:123)   在org.neo4j.kernel.TopLevelTransaction.close(TopLevelTransaction.java:124)

在抛出异常之前,事务被标记为"仅回滚"。当我调用 CreateObjectiveTxTask.createObjectiveRuleRelationships(..)时会发生这种情况,这会导致调用 TypeRepresentationStrategyFactory.chooseStrategy(..)

 private static Strategy chooseStrategy(GraphDatabase graphDatabaseService) {
    try (Transaction tx = graphDatabaseService.beginTx()) {
        if (AbstractIndexBasedTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.Indexed;
        if (SubReferenceNodeTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.SubRef;
        if (LabelBasedNodeTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.Labeled;
        tx.success();
        return Strategy.Labeled;
    }
}

此方法创建了一个PlaceboTransaction,检测到GraphDatabase实例已经在使用Index策略,因此关闭了事务而没有尝试调用" success()"在它上面。

这是否可能导致RollbackException?

在调用" success()"之前,可能导致SDN关闭PlaceboTransaction的原因是什么?在它上面,我怎么能阻止SDN这样做呢?

1 个答案:

答案 0 :(得分:0)

也许 TyperRepresentationStrategyFactory.chooseStrategy(..)中存在错误 此代码的最新Git提交(b40ea309)将 tx.success()移动到仅在策略尚未使用时才影响事务的位置。

private static Strategy chooseStrategy(GraphDatabase graphDatabaseService) {
    Transaction tx = graphDatabaseService.beginTx();
    try {
        if (isAlreadyIndexed(graphDatabaseService)) return Strategy.Indexed;
        if (isAlreadySubRef(graphDatabaseService)) return Strategy.SubRef;
        if (isAlreadyLabeled(graphDatabaseService)) return Strategy.Labeled;
 } finally {
        tx.success();tx.finish();
     }

成为

    try (Transaction tx = graphDatabaseService.beginTx()) {
        if (AbstractIndexBasedTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.Indexed;
        if (SubReferenceNodeTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.SubRef;
        if (LabelBasedNodeTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.Labeled;
        tx.success();
         return Strategy.Indexed;
 }

当我还原此更改时,我不再看到RollbackException。