Spring @Transactional и Neo4j OGM session.getTransaction()

Какова корреляция между аннотацией Spring org.springframework.transaction.annotation.Transactional и методом Neo4j OGM org.neo4j.ogm.session.Session.getTransaction().

Я пытаюсь получить доступ к текущей транзакции через session.getTransaction() внутри метода, аннотированного Spring @Transactional, но всегда получаю значение null.

Я добавил следующий код внутри моего метода Spring MVC RestController:

Transaction tx = session.beginTransaction();
try {
        for (int i = 0; i < 10; i++) {
            initializeNode(node);
        }
    }
    tx.commit();
} catch (Throwable th) {
    logger.error("Error while inserting mock data", th);
    th.printStackTrace();
} finally {
    tx.close();
}

в случае следующего метода:

private void initializeNode(TestNode node) {
    System.out.println(session.getTransaction());
}

он печатает текущий tx - пока все в порядке.

Но в случае следующего метода:

private void initializeNode(TestNode node) {
    System.out.println(session.getTransaction());

    User admin = userDao.findByUsername("admin");
}

в первый раз он печатает текущий tx, а затем null... транзакция исчезает перед фиксацией по какой-то причине..

это метод findByUsername:

@Service
@Transactional
public class UserDaoImpl implements UserDao {

    @Override
    @Transactional(readOnly = true)
    public User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }
...
}

Сразу после этого при фиксации я получаю следующее исключение:

org.neo4j.ogm.exception.TransactionManagerException: Transaction is not current for this thread
    at org.neo4j.ogm.session.transaction.DefaultTransactionManager.commit(DefaultTransactionManager.java:100)
    at org.neo4j.ogm.transaction.AbstractTransaction.commit(AbstractTransaction.java:83)
    at org.neo4j.ogm.drivers.embedded.transaction.EmbeddedTransaction.commit(EmbeddedTransaction.java:77)

Что я делаю не так ? Почему транзакция исчезает?


person alexanoid    schedule 12.07.2016    source источник


Ответы (1)


В этом вопросе есть несколько вопросов и тем. Я постараюсь разобрать их, и, надеюсь, в конце все будет иметь смысл.

Начиная с последней версии Spring Data Neo4j (4.1.x) нет никакой корреляции между Spring @Transactional и Neo4j OGM Session.getTransaction() или Session.beginTransaction() при прямом вызове.

В первых двух блоках кода вы полностью управляете жизненным циклом сеанса OGM напрямую. На данный момент Spring вообще не задействован, и, как вы говорите, он выполняется, как и ожидалось.

В вашем обновленном третьем блоке кода вы теперь ожидаете, что сеанс, который вы открыли вручную, будет работать с вашим DAO, управляемым Spring. То, что здесь произойдет, зависит от драйвера Neo4j, который вы используете с SDN, но, по сути, поскольку ваш DAO имеет аннотацию @Transactional, Spring перехватит вызов и начнет новую транзакцию самостоятельно поверх той, которой вы управляете вручную. На данный момент мы не можем дать никаких гарантий относительно поведения, но самым простым объяснением было бы сказать, что оно будет неожиданным (опять же, в зависимости от используемого драйвера).

Итак, как вы можете это исправить?

Я предполагаю, что вы хотите использовать Spring Transactions и Spring Data Neo4j. Если это так, вам нужно начать с:

  1. Изменение вашего DAO для использования Spring Data Repositories. Это дает вам множество бесплатных функций сохранения, таких как поиск, сохранение, удаление и т. д.
  2. Поместите аннотацию @Transactional вокруг единицы работы, которую вы хотите выполнить. У вас может быть метод, который вызывает userRepository.findByUserName(), изменяет этого пользователя и вызывает userRepository.save(user). В веб-среде это обычно какой-то метод обслуживания.
  3. Удаление любого кода, который вручную запускает или завершает транзакцию сеанса OGM.

Вы можете найти очень короткий пример кода здесь и более длинный пример кода здесь.

Более подробное руководство также можно найти здесь.

В Spring Data Neo4j 4.2.x мы надеемся представить более мощное и дружественное поведение @Transactional, так что следите за обновлениями.

person digx1    schedule 13.07.2016