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

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)" 已经存在

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

阅读 2.3k
1 个回答

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

但你的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);
        }
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题