回滚异常:由PlaceboTransaction上的close()未成功()引起



自从我的Neo4j从1.9.8升级到2.1.2。以及从3.2.0到3.2.5的Spring Data,当我试图从事务中调用TopLevelTransaction.colose(..)时,我看到了一个"回滚异常"。如果线程没有关联的事务,则不会发生这种情况。

neo4j.kernel.TopLevelTransaction.close(TopLevelTransaction.java:134)~[neo4j-kernel-2.1.2.jar:2.1.2]
网址:org.neo4j.kernel.TopLevelTransaction.fining(TopLevelTransaction.java:111)

导致原因:javax.transaction.RollbackException:提交失败,事务回滚
网址: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(..)[/em>.

 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()"。

这是否可能导致回滚异常?

是什么原因导致SDN在调用"success()"之前关闭PlaceboTransaction,以及如何阻止SDN这样做?

也许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;
 }

当我恢复此更改时,我不再看到回滚异常。

最新更新