Я пытаюсь эмулировать распределенное приложение с parallelStream()
, пишу в БД, где комбинации записей должны быть уникальными. Тем не менее, я пробовал несколько вариантов из @Transactional
и @Lock
, но ни один из них не работает.
Вот часть кода, которая должна прояснить проблему:
В AtomicDbService
:
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
public TestEntity atomicInsert(TestEntity testEntity) {
TestEntityParent testEntityParent = testEntityParentRepository
.findByStringTwo(testEntity.getTestEntityParent().getStringTwo())
.orElseGet(() -> testEntityParentRepository.save(TestEntityParent.builder()
.stringTwo(testEntity.getTestEntityParent().getStringTwo())
.build()));
return testEnityRepository.findByStringAndTestEntityParentStringTwo(
testEntity.getString(), testEntity.getTestEntityParent().getStringTwo()
).orElseGet(() -> testEnityRepository
.save(
TestEntity.builder()
.string(testEntity.getString())
.testEntityParent(testEntityParent)
.build()
)
);
}
Тест:
@Test
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
public void testOperationsParallelStream() {
List<Integer> list = IntStream.range(0, 3).boxed().collect(Collectors.toList());
list.parallelStream().forEach(lala -> atomicDbService.atomicInsert(testEntity));
System.out.println(testEnityRepository.findAll());
}
В качестве вывода я получаю, например ::
[TestEntity(id=4, string=test, testEntityParent=TestEntityParent(id=3, stringTwo=testTwo)), TestEntity(id=5, string=test, testEntityParent=TestEntityParent(id=1, stringTwo=testTwo))]
Но на самом деле это должен быть только один результат. Другие темы, конечно, приводят к исключениям.