Поток безопасной пружины удалить данные - PullRequest
1 голос
/ 10 октября 2019

У меня есть две сущности с однозначной ассоциацией. И некоторые сервисы, которые работают с ними параллельно. Мне нужно удалить одну, но иногда у меня есть DataIntegrityViolationException, что, как я понимаю, означает, что я не могу удалить какую-то сущность, в то время как у другой есть внешний ключ.

Вот мои сущности:

public class Foo{

    @Id
    @GeneratedValue
    private Long id;

}

and:

public class Bar{

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Foo foo;

}

Метод, который не работает (все репозитории исходят из JpaRepository):

    @Transactional
    public void deleteFoo(Long fooId) {        
            barRepository.deleteAllByFooId(fooId);            
            fooRepository.deleteById(fooId);
    }

И некоторый метод, который работает параллельно и ломает все:

    @Transactional
    public void method(Long fooId) {        
            ...
            Foo foo = fooRepository.findById(fooId);
            barRepository.save(new Bar(foo));
            ...
    }

Итак, у меня есть ConstraintViolationException, как я понимаю, потому что я пытаюсь удалить Foo, но у меня есть тот new Bar(foo) в method, который не был удален barRepository.deleteAllByFooId(fooId) в deleteFoo.

Мне нужен такой подход, как «метод удаления должен дождаться завершения всех текущих транзакций и затем запустить только одну транзакцию». Не могу использовать KeyLockManager, потому что реальная структура проекта уже достаточно сложна, и если я ее использую, во многих классах должна быть одна и та же блокировка.

1 Ответ

0 голосов
/ 10 октября 2019

Проблема в том, что вы пытаетесь удалить объект, который используется в транзакции. Чтобы закрыть транзакцию, вы можете использовать метод save() в репозитории.

Также вам следует взглянуть на каскады и удаление сирот . Используйте вот так:

В Bar сущности:

@ManyToOne(cascade = CascadeType.REMOVE, orphanRemoval = true)
private Foo foo;

И удалите вот так:

barRepository.save(bar);

или около того:

...