使用Spring Data Neo4j的简单对象/图形映射来获取事务的正确方法?

时间:2012-01-07 19:59:15

标签: spring transactions neo4j spring-data-graph spring-data-neo4j

我在Spring Data Neo4j 2.0中使用简单的对象/图形映射,在那里我使用Spring Data存储库框架执行持久性操作。我正在使用存储库而不是使用Neo4jTemplate。我将存储库注入我的Spring Web MVC控制器,控制器直接调用repos。 (没有中间服务层 - 我的操作通常是CRUD和查找器查询。)

当我阅读操作时,没有问题。但是当我写操作时,我会得到" NotInTransactionException"。我的理解是,Neo4j中的阅读操作不需要交易,但写操作可以。

假设我想坚持使用简单的OGM,那么在这里进行交易的最佳方法是什么?我想要使​​用@Transactional,但是将它放在各种存储库接口上并不起作用。如果我在控制器和存储库之间引入一个中间服务层,然后使用@Transactional注释服务bean,那么它可以工作,但我想知道是否有更简单的方法。如果没有Spring Data,我通常可以访问DAO(存储库)实现,因此如果我想避免传递服务层,我可以用@Transactional注释具体的DAO。使用Spring Data,repos是动态生成的,因此看起来不是一个选项。

1 个答案:

答案 0 :(得分:7)

首先,请注意,拥有事务性DAO通常不是一个好习惯。但是如果你没有服务层,那就把它放在DAO上。

然后,您可以启用声明式事务。我是这样做的:

首先,定义一个名为@GraphTransactional的注释:

@Retention(RetentionPolicy.RUNTIME)
@Transactional("neo4jTransactionManager")
public @interface GraphTransactional {

}

更新: spring-data-neo4j添加了这样的注释,因此您可以重复使用它而不是创建新注释:@Neo4jTransactional

然后,在applicationContext.xml中,有以下内容(neo4jdbEmbeddedGraphDatabase):

<bean id="neo4jTransactionManagerService"
    class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
    <constructor-arg ref="neo4jdb" />
</bean>
<bean id="neo4jUserTransactionService" class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
    <constructor-arg ref="neo4jdb" />
</bean>

<bean id="neo4jTransactionManager"
    class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="neo4jTransactionManagerService" />
    <property name="userTransaction" ref="neo4jUserTransactionService" />
</bean>

<tx:annotation-driven transaction-manager="neo4jTransactionManager" />

请记住,如果您还使用其他事务管理器,则必须为此注释驱动的定义指定order="2",并且还要记住,如果您没有两阶段提交,则你有一个声明为sql和neo4j transactional的方法。