如何使用现有Transaction获取XAResource?

时间:2014-05-23 08:35:02

标签: neo4j

我的用例是:

我有一个现有的JTA TransactionManager和一个正在进行的交易。我想在此事务中将Neo4j作为XAResource登记,以便它可以在适当的2PC中准备/提交。

我没有在Neo4j中看到公共XAResource实现;一切似乎都是通过NioNeoDbPersistenceSource>进行路由的。 NeoStoreXaDataSource> NeoStoreXaConnection.NeoStoreXaResource。

是否有一种首选的方式在JTA交易中登记Neo4j,而不是由自己的TransactionManager提供的那些?我发现的所有测试用例都是模拟“FakeXAResource”[1]

赞赏!

S, ALR

[1]例如UseJOTMAsTxManagerIT

1 个答案:

答案 0 :(得分:0)

好的,我有一个我认为是Neo4j可以处理的最好的解决方案,尽管我对此并不感到兴奋。 :)

https://gist.github.com/ALRubinger/b584065d0e7da251469a

这个想法是这样的:

1)实施Neo4j的AbstractTransactionManager

这个笨重的类是JTA TransactionManager,Neo4j Lifecycle和其他一些方法的组合;我不完全清楚其中的一些(例如" getEventIdentifier()"或" doRecovery()")应该是什么,并且合同感觉超过指定。在Neo4j不是TransactionManager的权威所有者的情况下,我不确定为什么我们想要生命周期方法。

2)实施Neo4j的TransactionManagerProvider

这将允许您创建AbstractTransactionManager实现的新实例,但它受JDK服务SPI的约束,因此您必须提供无参数构造函数并找到一些其他智能/ hacky方式传递上下文信息英寸

3)创建META-INF / services / org.neo4j.kernel.impl.transaction.TransactionManagerProvider文件,其中包含来自步骤2的TransactionManagerProvider impl的FQN内容。

4)当你创建一个新的GraphDatabaseService时,传入如下的配置:

final GraphDatabaseService graphDatabaseService = new GraphDatabaseFactory().
            newEmbeddedDatabaseBuilder(FILE_NAME_STORAGE).setConfig(
            GraphDatabaseSettings.tx_manager_impl.name(),
            "NAME_OF_YOUR_TXM_PROVIDER")
            .newGraphDatabase();

然后使用不推荐使用的API(GraphDatabaseAPI)访问TransactionManager:

// Get at Neo4j's view of the TransactionManager
final TransactionManager tm = ((GraphDatabaseAPI)   graphDatabaseService).getDependencyResolver().resolveDependency(TransactionManager.class);
tm.begin();
final Transaction tx = tm.getTransaction();

我使用这种方法的真正问题是我们必须使用来自Neo4j的TransactionManager实现,它正在包装真正的TM。我想要做的是使用我的TM并将Neo4j作为XAResource登记。

所以我还没有找到办法做到这一点,从Neo4j测试套件来看,我认为目前可能没有任何提供的XAResource支持。< / p>

绝对愿意并希望得到纠正! :)

但是如果我没有提到上面提到的观点,附加的要点就会起作用,并使用外部的TransactionManager(Narayana,我们JBoss)作为支持实现来展示Neo4j。

S, ALR