SpringJPA问题,涉及到事务的逻辑

发布于 2022-09-11 18:44:45 字数 1123 浏览 37 评论 0

1.外层方法(methodA),没有带事务注解,然后方法里调用某个Service的某个方法,该方法(methodB)带着事务注解。方法B里是对某个Repository的deleteAll ,接着再save。有点抽象,直接看代码:

//实体类,Dev
@Table(name = "tbl_dev")
public class Dev implements Serializable, Cloneable {


    /** 自增ID */
    @Id
    @GeneratedValue
    private Long id;

    /** 设备标签 */
    @Column(name = "dev_name")
    private String name;
    。
    。
    。

注意name字段是唯一键约束的,接着methodA:

            public void methodA() {
                    ...
                    //先获取到
                    devs = devRepository.findAll();
                    devService.methodB(devs);
                    ...
            }
                  
                   

methodB是这样的:

 @Transactional
    public void methodB(List<Dev> devs) {
        devRepository.deleteAll();
        if (!devs.isEmpty()) {
            devRepository.save(devs);
        }
    }

这样,当在controller里执行方法A,总会报错:

错误: 重复键违反唯一约束"tbl_dev_dev_name_key"
  详细:键值"(dev_name)=(XXX)" 已经存在

为什么会这样呢?事务里不是先删除所有,再重新插进去吗?然后整个事务一起提交上去就会有这个问题。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

残花月 2022-09-18 18:44:45

我刚才用你这个逻辑测试,执行是没问题的。是可以重新插入的。

但你的save()方法是重新自己封装的吗?因为springJPA里面的save()方法只能接受一个实体对象,要保存一个List的实体对象时候是应该用saveAll()

下面是我的测试代码

    @Test
    public void testA() {
        List<BookWordEN> bookWordENS = bookWordENDao.findAll();
        methodB(bookWordENS);
    }

    @Commit
    @Transactional
    public void methodB(List<BookWordEN> bookWordENList) {
        bookWordENDao.deleteAll();
        if (!bookWordENList.isEmpty()) {
            bookWordENDao.saveAll(bookWordENList);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文