2012-12-14 91 views
4

我對使用事務處理異常有疑問。爲了表述清楚我的問題,我想表明我的配置:Spring Transaction中需要異常處理嗎?

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="transactionInterceptor" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager" ref="transactionManager" /> 
    <property name="transactionAttributeSource"> 
     <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" /> 
    </property> 
</bean> 

<bean id="baseService" abstract="true"> 
    <property name="daoProvider" ref="daoProvider" /> 
</bean> 

<bean id="customerService" parent="transactionInterceptor"> 
    <property name="target"> 
     <bean class="com.edfx.adb.service.CustomerService" parent="baseService" /> 
    </property> 
</bean> 

<bean id="daoProvider" class="com.edfx.adb.dao.provider.DaoProvider"> 
    <property name="customerDao" ref="customerDao" /> 
</bean> 

<bean id="customerDao" class="com.edfx.adb.dao.CustomerDao"> 
    <constructor-arg value="#{T(com.edfx.adb.persist.entity.Customer)}" /> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

活動事務類是:

@Transactional 
public class CustomerService extends BaseService implements ICustomerService { 

    @Transactional(readOnly = true) 
    public Customer getCustomerById(String id) { 
     return getDaoProvider().getCustomerDao().getCustomerById(id); 
    } 

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class }) 
    public void addNewCustomer(CustomerDTO customerDTO) { 
     Customer customer = new Customer(); 

     customer.setCustomerId(customerDTO.getCustomerId()); 
     customer.setCustomerName(customerDTO.getCustomerName()); 
     customer.setActive(customerDTO.isActive()); 

     getDaoProvider().getCustomerDao().save(customer); 
    } 
} 

我的疑惑在於方法addNewCustomer。我已經設置了rollbackFor = { Throwable.class }

它是如何工作的?

還做我需要明確地處理異常,如:

@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class }) 
public boolean addNewCustomer(CustomerDTO customerDTO) { 
    Customer customer = new Customer(); 

    customer.setCustomerId(customerDTO.getCustomerId()); 
    customer.setCustomerName(customerDTO.getCustomerName()); 
    customer.setActive(customerDTO.isActive()); 

    try { 
     getDaoProvider().getCustomerDao().save(customer); 
    } catch (Throwable throwable) { 
     return false; 
    } 

    return true; 
} 

強行我已經刪除從客戶表中的列上創建一個例外,但例外是不是在try-catch塊來抓,相反,我可以從託管的bean中調用addNewCustomer方法來捕獲該異常。

回答

8

這是春天文檔的摘錄

在其默認的配置,Spring框架的事務 基礎設施代碼只在回退功能標記事務運行的 ,未檢查異常;也就是說,拋出的異常 是RuntimeException的一個實例或子類。 (錯誤也會 - 默認爲 - 導致回滾)。檢查從事務性方法拋出的異常 不會導致在默認 配置中回滾。

您設置了rollbackFor = Throwable.class,現在Spring將回滾任何異常/錯誤。默認情況下,無論我們喜歡與否,Spring將僅針對RuintimeException進行回滾,否則將提交

+0

強制我創建了一個異常,從客戶表中刪除一列,但是這個異常沒有在try-catch塊中被捕獲,而是我可以從託管bean中捕獲那個我調用了'addNewCustomer'方法的異常。 –

+1

實際上,在具體的情況下,rollbackFor = Throwable.class是沒有意義的,因爲addNewCustomer不能拋出任何checked異常,因爲它沒有聲明任何異常,並且RuntimeExceptions被默認捕獲。 –

+0

謝謝你的解釋。請告訴我,春天的XML配置好嗎? –

6

Spring框架只拋出RuntimeExceptions,從技術上講,你永遠不必捕捉任何異常。

+0

謝謝。春天的xml配置是否正常? hibernate的save方法thorws Hibernate異常。我不需要處理它嗎? –

+0

發佈例外 –

+0

我沒有得到任何異常。我正在編寫代碼,在編寫時我很好奇異常處理。我試圖讓我的代碼錯誤免費。 –