Я написал небольшое приложение Spring Boot, которое использует spring-boot-starter-data-neo4j
для подключения к экземпляру Neo4j.
Я хотел бы выполнить некоторые обновления с помощью запросов Cypher, но не могу заставить работать управление транзакциями при открытии файла Session
с использованием файла SessionFactory
. Управление транзакциями прекрасно работает с использованием аннотированных объектов OGM через файл Neo4jRepository
.
В целях тестирования я написал два простых сервиса, аннотированных @Transactional
:
Используя аннотированный класс OGM и Neo4jRepository
:
@Service
@Transactional
public class OgmServiceImpl implements OgmService {
private final PersonRepository personRepository;
public OgmServiceImpl(PersonRepository personRepository) {
this.personRepository = personRepository;
}
@Override
public void storeData() {
personRepository.save(new Person("Jack"));
if (true) {
throw new IllegalStateException();
}
personRepository.save(new Person("Jill"));
}
}
При выполнении метода storeData() ни Джек, ни Джилл не сохраняются в Neo4j. Работает как положено.
Другой сервис делает то же самое, выполняя запросы Cypher на Neo4j Session
:
@Service
@Transactional
public class CypherServiceImpl implements CypherService {
private final SessionFactory sessionFactory;
public CypherServiceImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void storeData() {
Session session = sessionFactory.openSession();
session.query("CREATE (p:Person { name: 'Jack' })", Map.of());
if (true) {
throw new IllegalStateException();
}
session.query("CREATE (p:Person { name: 'Jill'})", Map.of());
}
}
Однако управление транзакциями не удается, так как Джек хранится в Neo4j.
Для меня такое поведение довольно неожиданно. Я могу заставить работать управление транзакциями, явно запустив транзакцию, но мне это не нравится:
public void storeData() {
Session session = sessionFactory.openSession();
try (Transaction tx = session.beginTransaction()) {
session.query("CREATE (p:Person { name: 'Jack' })", Map.of());
if (true) {
throw new IllegalStateException();
}
session.query("CREATE (p:Person { name: 'Jill'})", Map.of());
tx.commit();
}
}
Нужно ли мне самому настраивать SessionFactory
, чтобы это работало? Почему Spring Boot не позаботится об этом?
sessionFactory.openSession()
наsessionFactory.getCurrentSession()
? - person Shababb Karim   schedule 10.09.2020