我在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是动态生成的,因此看起来不是一个选项。
答案 0 :(得分:7)
首先,请注意,拥有事务性DAO通常不是一个好习惯。但是如果你没有服务层,那就把它放在DAO上。
然后,您可以启用声明式事务。我是这样做的:
首先,定义一个名为@GraphTransactional
的注释:
@Retention(RetentionPolicy.RUNTIME)
@Transactional("neo4jTransactionManager")
public @interface GraphTransactional {
}
更新: spring-data-neo4j添加了这样的注释,因此您可以重复使用它而不是创建新注释:@Neo4jTransactional
然后,在applicationContext.xml
中,有以下内容(neo4jdb
是EmbeddedGraphDatabase
):
<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的方法。