在自动刷新/提交期间Spring Hibernate回滚失败,留下事务方法

时间:2017-04-12 20:35:04

标签: spring hibernate transactions

这是我的第一篇文章,所以我真的一定要摸不着头脑,因为这里的资源非常好。

Spring MVC 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);

典型的dao就是这样做:

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

一开始,我从正常的POJO调用上述事务方法'进程':

        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问题或NOT NULL列)为null时,它不会回滚。

引用是故意的,因为我意识到它并没有像我想的那样从'process'方法中的错误实际上成功回滚,因为它还没有写入数据库。这是退出吗?

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

我已尝试在'process'方法中对所有内容进行try / catch,但因为没有错误发生(当它离开方法时动作开始了!)然后没有任何东西抛出并被捕获。

调用pojo确实捕获了一个错误(并且可以看到非null的数据异常错误),但是它已经将对象写入数据库并在错误发生之前将它们保留在那里。

rollbackFor很好,但是故障似乎是在那之后 - 它在该方法中捕获错误,但是当它离开方法并且Spring / Hibernate做了它的事情并且提交......它留在数据库上。没有回滚。所以rollbackFor似乎只适用于相关方法中的错误,而不是在(后写)

之后自动发生的事情

几乎像自动提交行为,但不应该是Hibernate(Oracle 10)的情况。

有什么想法?我今天会在今天放一个flush(),看看是否会在进程方法中发生错误,因此被rollbackFor抓住......但我们不应该这样做吗? (如果有效)

由于

1 个答案:

答案 0 :(得分:0)

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

<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   {

当我有两个时,这是为了更改事务管理器名称,加上(它改变的原因)。类似的@Transactional(值=另一个的设置。

干杯