Използвам Neo4j в самостоятелен режим с Spring Data за Neo4j в моето приложение. Моят код трябва да може да гарантира, че когато се опитам да запазя обект, или всичко влиза, или нищо не влиза. Знам, че транзакциите не се поддържат през REST в Spring Neo4j, но групова операция в REST API на Neo4j трябва да е добре за настоящите ми нужди. Няма толкова много операции, но цялото извикване на save() трябва да бъде всичко или нищо.
Изглежда обаче, че Spring не прави това по подразбиране. Ако по време на записа възникне RuntimeException, в базата данни все още ще има частични данни. Бих искал да продължа да използвам интерфейса на GraphRepository, но ако това не е възможно, предполагам, че мога да внедря това ръчно.
Ето малко опростен примерен код, за да илюстрирате какво се случва
POJO:
@NodeEntity
public class TestObject {
@GraphId
private Long id;
private String name;
@Fetch
@RelatedTo(type = "SIBLING_OF", direction = Direction.BOTH)
private Set<TestObject> siblings;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
if (name == "fail") {
throw new RuntimeException();
}
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TestObject> getSiblings() {
return siblings;
}
public void setSiblings(Set<TestObject> siblings) {
this.siblings = siblings;
}
}
Хранилище
public interface TestRepository extends GraphRepository<TestObject>{}
Тест
public class Test {
@Autowired
TestRepository repo;
public void run() {
final TestObject o1 = new TestObject();
o1.setName("good1");
final TestObject o2 = new TestObject();
o1.setName("good2");
final TestObject o3 = new TestObject();
o1.setName("good3");
final TestObject o4 = new TestObject();
o1.setName("fail");
o1.setSiblings(new HashSet<TestObject>() {{
add(o2);
add(o3);
add(o4);
}});
//throws exception, but o1 node is created in Neo4j
repo.save(o1);
}
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("context.xml");
Test t = (Test) appContext.getBean("test");
t.run();
}
}