2017-04-12 96 views
0

這是我的第一篇文章,所以我真的必須抓我的頭,因爲這裏的資源非常好。春季Hibernate回滾失敗在自動沖洗/提交離開交易方法

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; 
    } 

(這番話不太對勁,數據庫事務開始,在「過程」方法結束。)

所以 - 當出現在「過程」這一切「代碼中的錯誤被回滾'(引用故意)。但是,當數據庫錯誤(如FK問題)或NOT NULL列保留爲空時,它不會回滾。

上述引用是故意的,因爲我意識到它實際上並沒有成功回滾'process'方法中的錯誤像我想的那樣,因爲它沒有寫入數據庫。這是否退出?

數據庫錯誤發生在進程方法和調用pojo之間。 Hibernate存儲了第一級數據並開始向數據庫寫入所有對象。我試過在'process'方法裏放一個try/catch,但是因爲沒有發生錯誤(它是當它離開方法時動作開始!),所以沒有任何拋出和被捕獲的東西。

調用pojo確實會捕獲一個錯誤(並且可以看到數據異常錯誤爲非空),但它已將對象寫入數據庫並在錯誤發生之前將它們留在那裏。

rollbackFor是好的,但錯誤似乎是在那之後 - 它捕獲該方法中的錯誤,但是當它離開該方法並且Spring/Hibernate做了它的事情並提交時...它留在數據庫中。沒有回滾。所以rollbackFor似乎只適用於相關方法中的錯誤,而不是在發生後自動發生(寫入後)

幾乎像自動提交行爲,但不應該是Hibernate(Oracle 10)的情況。

有什麼想法?我將在今天放一個flush(),看看是否會使錯誤發生在進程方法中,因此被rollbackFor捕獲,但是我們不應該這樣做? (如果可以的話)

謝謝

回答

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(值=設置另一個。

乾杯