【问题标题】:SQLIntegrityConstraintViolationException cause Spring Transaction RollbackSQLIntegrityConstraintViolationException 导致 Spring 事务回滚
【发布时间】:2021-05-14 06:31:55
【问题描述】:

春季 4.1.4 休眠 4.2.0 JDK 1.8

我的上下文:我有一个 Controller 调用 --> Service --> 调用 Dao 业务功能是删除(在一对多数据库关系中)一些孩子,但不是所有孩子。 然后,在删除一些孩子之后,我尝试删除父级,然后我得到了 java.sql.SQLIntegrityConstraintViolationException

但问题是为什么交易是回滚的市场? (换句话说,为什么我没有删除一些孩子?)

SQLIntegrityConstraintViolationException 是一个检查异常,并说明 Spring 文档的行为与 EJB 相同:Note that by default, rollback happens for runtime, unchecked exceptions only. The checked exception does not trigger a rollback of the transaction.

如果可能的话,我需要删除一些子节点并尝试删除父节点,否则我需要提交维护父节点和剩余子节点的事务 注意我还尝试在 Service 和 Dao 方法中指定 Spring Annotation

@Transactional(noRollbackFor = SQLIntegrityConstraintViolationException.class)

明确要求预期的行为,但对我来说甚至不像这样工作

控制器代码方法:

public void delete() {
    FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Data deleted.","");
    
    try{
        memoTemplateService.delete(memoTemplate);
        memoTemplates.remove(memoTemplate);
    }
    catch (Exception e){
        msg=new FacesMessage(FacesMessage.SEVERITY_WARN, "A","B");
    }
    reset();

    
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

服务方式:

@Override
@Transactional(noRollbackFor =  {SQLIntegrityConstraintViolationException.class,DBConstraintException.class})
public void delete(MemoTemplate memoTemplate)throws BusinessException {
    // deleting some ,not all , child 
    phaseAndMemoGenerator.deleteMemosForVisibleTimeHorizon(memoTemplate);
    try{// some times Template cannot be deleted
        memoTemplateDao.delete(memoTemplate);
    }
    catch (Exception e){
        throw new DBConstraintException("Partial Delete", "Template cannot be deleted, Memo in the past are present");
    }
}

@Repository(value = "memoTemplateDao")
public class MemoTemplateDaoImpl extends GenericJpaDaoImpl<MemoTemplate,  Long> implements MemoTemplateDao {

@Override
@Transactional(noRollbackFor = SQLIntegrityConstraintViolationException.class)
public void delete(MemoTemplate t) {
    super.delete(t);
    em.flush();
}
}

只是一个更新:这太不可思议了,但我无法在 Dao 方法中执行 catch ,调试器进入 catch 块,但在此之前仍然触发 java.sql.SQLIntegrityConstraintViolationException,太不可思议了!

@Transactional(noRollbackFor = {SQLIntegrityConstraintViolationException.class,PersistenceException.class})
public void tryToDelete(MemoTemplate t)throws Exception {
    super.delete(t);
    try{
        em.flush();
    }
    catch (Exception e){
        throw new Exception("ddddd");
    }
}

【问题讨论】:

    标签: spring spring-transactions


    【解决方案1】:

    如果在 DB 中定义了约束,您将无法通过不回滚的方式提交来绕过它们。

    【讨论】:

    • 情况是:relation 1 to many as A 1-->N B 然后我需要根据一些逻辑删除孩子B的一些记录。由于我事先不知道将删除多少条记录 B,因此我将尝试删除父 A(以防所有子都已删除);如果父删除失败,我希望提交事务,因为我保留有关已删除子项的工作。在 DAO 处抛出 SQLIntegrityConstraintViolationException 并将 PersistentException 返回到 SERVICE 。现在第一个 Exception 不会回滚事务,它是 CHECKED EXCEPTION 。第二个是 UNcheched 但我把 noRollbackFor
    猜你喜欢
    • 2017-07-31
    • 1970-01-01
    • 2020-03-10
    • 2011-11-21
    • 2016-07-26
    • 1970-01-01
    • 2016-09-19
    • 2017-03-03
    • 2012-03-10
    相关资源
    最近更新 更多