【问题标题】:EntityManager persist() with @Transactional does not throw DataIntegrityViolationException带有@Transactional 的EntityManager persist() 不会抛出DataIntegrityViolationException
【发布时间】:2020-01-07 08:45:12
【问题描述】:

我们有 EntityManager persist() 和 @Transactional。如果插入的数据超过列长度,persist 不会抛出 DataIntegrityViolationException。当带有@Transactional 的2-level up 父方法返回时抛出。

class Worker {

    @Transactional
    public Integer createEmployee(String name) { 
        // employeeId is generated after checking if employee exists or not
        saveEmployee(name, employeeId);
        send_to_third_party(employeeId);
        return employeeId;
    }

    saveEmployee(String name, Integer employeeId){
        Employee em = new Employee();
        // Get other data for employee like department etc.
        dao.persist(employee);
    }
}

class Dao {
    @autowired
    EntityManager em;

    @Transational
    public void persist(Object object) {
        try{
            em.persist(object);
            log("successful");
        }
        catch(RuntimeException ex) {
            log("persist failed");
            throw ex;
        }
    }
}

如代码所示,saveEmployee即使出现数据长度大于列长度的错误也会返回成功。将employeeId 发送给第三方并进行处理。当 createEmployee 返回employeeId 时,它会抛出异常“DataIntegrityViolationException”并显示消息“字符串或二进制数据将被截断”。最后,员工没有保存在我们的数据库中,而是由第三方处理,这会在系统中造成不匹配和进一步的错误。

dao.persist() 中的@Transactional 不会提交persist 操作吗?为什么抛出异常需要这么长时间?

感谢您的帮助。

附: - 我们肯定会检查数据长度。

【问题讨论】:

    标签: java sql hibernate spring-boot


    【解决方案1】:

    persist() 只会使对象被管理和持久化,它实际上不会对数据库做任何事情,直到事务上下文关闭。要强制与数据库立即同步,请在persist() 之后调用flush()。这将导致立即抛出异常。

    【讨论】:

    • 我个人也是会在事务方法成功后才调用第三方。
    • persist() 没有自己的事务上下文吗? persist() 和数据库对象刷新后不会关闭吗?
    • @Strelok,它很少那么简单。如果远程调用出错,您想回滚本地更改的内容?
    • @Nets 你混淆了数据库事务和休眠的事务上下文(当你使用@Transactional 进入/退出第一个方法时打开/关闭)。
    • @Captain,是的,我很困惑。两者都是 org.springframework.transaction.annotation.Transactional。它们如何具有不同类型的事务上下文?你的意思是flush() 在休眠事务关闭后发生,在这种情况下是saveEmployee()?如果没有@Transactionalpersist() 会刷新到数据库吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2018-03-10
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    相关资源
    最近更新 更多