Правильный способ получения транзакций, используя простое сопоставление объектов / графиков Spring Data Neo4j? - PullRequest
5 голосов
/ 07 января 2012

Я использую простое отображение объектов / графиков в Spring Data Neo4j 2.0, где я выполняю операции персистентности, используя среду репозитория Spring Data.Я работаю с репозиториями, а не с Neo4jTemplate.Я внедряю репозитории в мои контроллеры Spring Web MVC, и контроллеры вызывают репозитории напрямую.(Нет промежуточного сервисного уровня - мои операции обычно представляют собой CRUD и запросы поиска.)

Когда я выполняю операции чтения, проблем не возникает.Но когда я делаю операции записи, я получаю «NotInTransactionException».Насколько я понимаю, операции чтения в Neo4j не требуют транзакций, а операции записи требуют.

Какой лучший способ включить транзакции в картину, если я хочу придерживаться простого OGM?Я хочу использовать @Transactional, но поместить его в различные интерфейсы репозитория не работает.Если я ввожу промежуточный уровень обслуживания между контроллерами и репозиториями, а затем аннотирую служебные компоненты с помощью @Transactional, то это работает, но мне интересно, есть ли более простой способ сделать это.Без Spring Data у меня, как правило, был бы доступ к реализациям DAO (репозитория), поэтому я мог бы комментировать конкретные DAO с помощью @Transactional, если бы я хотел избежать сквозного уровня обслуживания.В Spring Data репозитории генерируются динамически, поэтому это не представляется возможным.

1 Ответ

7 голосов
/ 08 января 2012

Во-первых, обратите внимание, что транзакционные 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.

...