线程安全弹簧数据删除

时间:2019-10-10 07:57:15

标签: java spring spring-boot spring-data-jpa spring-data

我有两个具有一对一关联的实体。以及与它们并行工作的某些服务。我需要删除一个实体,但是有时我有DataIntegrityViolationException,据我了解,这意味着我无法删除某个实体,而另一个实体上却带有外键。

这是我的实体:

public class Foo{

    @Id
    @GeneratedValue
    private Long id;

}

和:

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 :(得分:-2)

问题是您尝试删除在事务中使用的实体。要关闭交易,您可以使用存储库的save()方法。

您还应该查看cascadesorphan removal。像这样使用:

Bar实体中:

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

然后像这样删除:

barRepository.save(bar);

等等: