当前位置: 首页 > 知识库问答 >
问题:

自动刷新/提交期间Spring Hibernate回滚失败

虞承泽
2023-03-14

这是我的第一篇文章,所以我真的必须挠头,因为这里的资源非常好。

SpringMVC 4.2.5。hibernate-core-5.1.0 JDK8

我遇到了一个问题,当离开一个被调用的@Transactional方法时,事务没有回滚。我调用的方法具有适当的设置:

@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor = Exception.class)
public byte process(CommonDataBlock commonDataBlock) throws Exception   {

该方法调用dao对象,假设我们保存了大约8个对象(“到数据库”),例如:

applicationPartyDao.saveApplicationParty(appParty);

对于典型的刀来说,它只是做一些类似的事情:

this.getSessionFactory().getCurrentSession().save(appParty);

首先,我从普通POJO调用上述事务方法“process”:

        try {
        // Database transaction starts/ends here
        submitAccess.process(commonDataBlock);
    }
        catch (Exception e) {
            logUtil.debug(this, "Error submitting application: "+e.getMessage());
            e.printStackTrace();
            return Codes.RET_BYPASS_ALL_ADAPTORS;
    }

(该注释不太正确,数据库事务以“process”方法开始和结束。)

因此,当“进程”中的代码出现错误时,所有代码都会“回滚”(有意引用)。但是,当出现数据库错误(例如FK问题)或非NULL列保留为NULL时,它不会回滚。

上面的引用是有意的,因为我意识到它实际上并没有像我想的那样成功地从“process”方法中的错误中回滚,因为它还没有写入DB。在退出时执行此操作。

数据库错误发生在进程方法和调用pojo之间。Hibernate已经存储了一级数据,并开始将所有对象写入数据库。

我已经尝试在“进程”方法中的所有内容周围放置一个try/catch,但是因为那里没有发生错误(当它离开方法时,操作就开始了!)那么就没有任何东西被抛出和捕获。

调用pojo确实捕捉到错误(并且可以看到非null的数据异常错误),但它已将对象写入数据库,并将它们留在错误之前。

回滚是好的,但故障似乎在那之后-它捕获该方法中的错误,但当它离开该方法时,Spring/Hibernate完成它的任务并提交。。。它留在数据库中。没有回滚。因此,rollbackFor似乎只适用于相关方法中的错误,而不适用于之后自动发生的错误(write behind)

几乎类似于自动提交行为,但Hibernate(Oracle 10)不应该是这种情况。

有什么想法吗?我今天会放一个flush()来看看这是否会在进程方法中发生错误,从而被rollback捕获...但是我们不应该这样做?(如果有效)

谢啦

共有1个答案

郭凡
2023-03-14

知道了。问题是我要更改事务管理器的名称:

<bean id="transactionManager_guardianship"  class="org.springframework.orm.hibernate5.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory_guardianship" />
    <property name="dataSource"><ref bean="dataSource_guardianship"/></property>
</bean>

如果你没有“transactionManager”,我会在某个地方读到它,它是找不到的。有道理(我也按名字查找上下文内容!很明显!)。我这样做是因为我有两个不同的数据库。

所以我添加了一个限定符:

<bean id="transactionManager_guardianship"  class="org.springframework.orm.hibernate5.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory_guardianship" />
    <property name="dataSource"><ref bean="dataSource_guardianship"/></property>
    <qualifier value="txGuardianship"/>
</bean>

...并引用服务类中的正确事务:

@Transactional(value="txGuardianship", propagation=Propagation.REQUIRED,readOnly=false,rollbackFor = Exception.class)
public byte process(CommonDataBlock commonDataBlock) throws Exception   {

这适用于事务管理器名称更改时,以及(更改原因)我有两个事务管理器时。类似@事务(值=另一个的设置。

干杯

 类似资料:
  • 所以,我是ajax新手,我正在尝试使用ajax和jquery提交表单,我想我已经弄清楚了服务器端的逻辑,因为当我加载页面时,它会自动提交,页面会很快刷新。空白表单将进入数据库,尽管其中有很多表单,因为页面会不断提交每次刷新。所以我认为我的服务器端正在工作,但我不知道该怎么做,不仅要阻止它刷新,还要使用html表单中的提交按钮进行提交。我在html页面中使用了thymeleaf。 这是我的html表

  • 问题内容: 如标题所述,我在应用程序中使用了休眠刷新模式机制。因此,当我更改休眠持久对象中的任何数据时,它会自动反映在数据库中。我不要这个 因此,我找到了使用FlushMode的解决方案。 所以这是我的实际问题: 最好使用冲洗模式代替?和 文档中此声明的含义是什么? 有时在执行查询之前会刷新会话,以确保查询从不返回过时状态。 http://docs.jboss.org/hibernate/orm/

  • 每个人, 我正在用Mysql学习springboot,并尝试将精力集中在事务上。我正在以下链接寻求指导: https://github.com/spring-guides/gs-managing-transactions/tree/master/complete 当我执行第一个事务时,将被保存。 当我执行第二个事务时,会被丢弃,因为Samuel违反了DB约束。 我现在想知道的是,1。当第二个事务失

  • 问题内容: 在JPA中,如果我们调用EntityTransaction.commit(),它会自动调用EntityManager.flush()吗?还是我们都应该称呼它们?有什么区别?因为我在使用JPA时遇到问题,所以当我向数据库中插入实体时,我会调用persist()。在数据库中,数据已插入(可以获取),但是该数据未显示在我的应用程序中(我使用findAll()进行获取)。在另一个实体上,它出现

  • 在JPA中,如果我们调用EntityTransaction。commit(),它是否自动调用EntityManager。flush()?或者我们应该叫他们两个?有什么区别?因为我对JPA有问题,当我向数据库插入实体时,我调用persist()。在数据库中,数据已经插入(可以提取),但该数据没有显示在我的应用程序中(我使用findAll()提取)。在另一个实体上,它出现了。有什么我不知道的吗?我使用

  • 我正在尝试编写一个具有事务和try/catch块的MS sql脚本。如果它捕获异常,则回滚事务。如果没有,则提交事务。我见过几个不同的网站说这样做: 但是,即使在捕获异常的情况下,我们也不会仍然命中“提交事务”行吗?这不会导致 SQL 错误,因为事务已经回滚吗?我认为应该这样做: 为什么通常发布的解决方案不包括@成功变量?提交已经回滚的事务时没有发生sql错误吗?我说第一个代码示例的“提交事务”行