我正在尝试实现一个 TransactionEventHandler
,就像 neo4j-versioning
中使用的那样为了创建时间机器风格,版本化的 Neo4j 数据库,现在使用 Neo4j 2.x。它因以下无限堆栈跟踪而失败:
javax.transaction.SystemException: TM has encountered some problem, please perform necessary action (tx recovery/restart)
at org.neo4j.kernel.impl.transaction.TxManager.assertTmOk(TxManager.java:349)
at org.neo4j.kernel.impl.transaction.TxManager.setRollbackOnly(TxManager.java:758)
at org.neo4j.kernel.TransactionEventHandlers.beforeCompletion(TransactionEventHandlers.java:120)
at org.neo4j.kernel.impl.core.TransactionEventsSyncHook.beforeCompletion(TransactionEventsSyncHook.java:68)
at org.neo4j.kernel.impl.transaction.TransactionImpl.doBeforeCompletion(TransactionImpl.java:368)
at org.neo4j.kernel.impl.transaction.TxManager.commit(TxManager.java:398)
at org.neo4j.kernel.impl.core.IsolatedTransactionTokenCreator.getOrCreate(IsolatedTransactionTokenCreator.java:61)
at org.neo4j.kernel.impl.core.TokenHolder.createToken(TokenHolder.java:114)
at org.neo4j.kernel.impl.core.TokenHolder.getOrCreateId(TokenHolder.java:102)
at org.neo4j.kernel.impl.api.store.DiskLayer.propertyKeyGetOrCreateForName(DiskLayer.java:367)
at org.neo4j.kernel.impl.api.store.CacheLayer.propertyKeyGetOrCreateForName(CacheLayer.java:370)
at org.neo4j.kernel.impl.api.StateHandlingStatementOperations.propertyKeyGetOrCreateForName(StateHandlingStatementOperations.java:939)
at org.neo4j.kernel.impl.api.DataIntegrityValidatingStatementOperations.propertyKeyGetOrCreateForName(DataIntegrityValidatingStatementOperations.java:67)
at org.neo4j.kernel.impl.api.OperationsFacade.propertyKeyGetOrCreateForName(OperationsFacade.java:397)
at org.neo4j.kernel.impl.core.NodeProxy.setProperty(NodeProxy.java:205)
...
这是我的测试:
@Test
public void test() {
GraphDatabaseService graphDb = new TestGraphDatabaseFactory().newImpermanentDatabase();
Node referenceNode = null;
try (Transaction transaction = graphDb.beginTx()) {
referenceNode = graphDb.createNode();
transaction.success();
}
VersioningTransactionEventHandler versioningTransactionEventHandler = new VersioningTransactionEventHandler(referenceNode);
graphDb.registerTransactionEventHandler(versioningTransactionEventHandler);
try (Transaction tx = graphDb.beginTx()) {
Node node = graphDb.createNode();
tx.success();
}
graphDb.shutdown();
}
这是VersioningTransactionEventHandler
:
public class VersioningTransactionEventHandler implements TransactionEventHandler<Object> {
private final Node versionDataNode;
public VersioningTransactionEventHandler(Node versionDataNode) {
this.versionDataNode = versionDataNode;
}
@Override
public Object beforeCommit(TransactionData data) throws Exception {
versionDataNode.setProperty("foo", "bar"); // <- this causes the error
return null;
}
@Override
public void afterCommit(TransactionData data, Object state)
{
}
@Override
public void afterRollback(TransactionData data, Object state)
{
}
}
我在我的应用程序中使用 org.neo4j.neo4j-2.0.1
和 org.neo4j.neo4j-kernel-2.0.1
。
为什么 setProperty()
会导致此错误?我该如何解决?非常感谢任何关于这里可能有问题的线索。
更新
正如 Michael Hunger 所建议的那样,我在传递节点之前执行了一个 setProperty()
,但现在测试静静地挂起无限大,没有任何反应。在节点上设置什么属性键值对并不重要:
...
referenceNode = graphDb.createNode();
referenceNode.setProperty("foo", "bar"); // <- results in hang
referenceNode.setProperty("herp", "derp"); // <- results in hang also
...
还有线索吗?我只想在事务事件处理程序中操作一个节点,就像在 1.9 version 中那样。 , 但 Neo4j 2.x 没有在构造函数中传递的 GraphDatabaseService#getReferenceNode()
方法。
最佳答案
首先,您似乎想要在 TransactionEventHandler 的 afterCommit() 方法中调用 incrementTransactionVersion()。这样,您就知道在增加版本之前事务已成功提交。我假设循环是由于增加版本节点的版本属性导致另一个事务引起的。要解决此问题,您可以检查 TransactionData 以查看当前事务是否由版本 Node 的更改引起。这并不像它可能的那样简单,但这里有一些伪 Java(我什至没有测试它是否编译)说明了如何完成此操作:
Iterable<PropertyEntry<Node>> ii = txData.assignedNodeProperties();
boolean doIncrementVersion = false;
for (PropertyEntry<Node> pEntry : txData.assignedNodeProperties()) {
if (pEntry.key().equals("transactionVersion") {
doIncrementVersion = true;
break;
}
}
if (doIncrementVersion) {
incrementTransactionVersion();
}
希望这对您有所帮助!
关于java - TransactionEventHandler 在 Node.setProperty() 上给出 javax.transaction.SystemException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23906091/