2011-07-15 95 views
2

我想在我的Web應用程序(由Spring MVC 3提供支持)中設置一個TransactionManager,因爲我需要一個註釋爲@Transactional的組件方法。TransactionManager和註解彈簧3問題

這是我的情況:

  • web.xml中:爲Spring的ContextLoaderListener(applicationContext.xml中和database.xml)
  • applicationContext.xml的負載2 XML文件:包含一些豆類,我可以」 t通過註釋定義,加上註解的標籤,加上通常的上下文:註釋配置和上下文:組件掃描(這個組件掃描包括包含@Transactional方法的包)
  • database.xml:包含數據源(我使用commons-dbcp的BasicDataSource),事務管理器定義和tx:annotat離子驅動。

我有一個@Component(DeleteComponent),它有一個接口和一個實現(DeleteComponentImpl)。實現類用@Component註釋,並且有一個公共方法用@Transactional註解(我註釋了具體類而不是接口,如Spring文檔所述)。對於@Transactional我沒有提出任何參數,因爲默認情況很好。這個類有一些DAO(用@Repository註解)通過@Autowired注入。我只使用普通的JDBC(沒有Hibernate或其他ORM)。這個@Component被注入一個@Controller(在spring-servlet.xml中定義)。

但是,如果註解爲@Transactional的方法拋出異常(未選中,如RuntimeException),則不會回滾任何內容。數據庫在異常之前保留更改。我使用Jetty Web服務器在本地測試我的應用程序。我注意到的事實是,似乎沒有設置事務管理器。實際上,我的事務管理器被命名爲「transactionManager」。該XML行成立註解驅動的事務是

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

<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

如果我改變它使用一個不存在的bean的名字一樣

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

應用程序仍然部署正確,不抱怨。

我應該檢查哪些技巧以使其工作?

謝謝。

+0

爲什麼不從您的主appcontext.xml導入database.xml?如何在spring-servlet.xml中定義appcontext?組件掃描基礎包與您的impl類的包相匹配? – abalogh

回答

2

我用@Transactional解決(的rollbackFor = RuntimeException.class)和開關BasicDataSource轉換爲c3p0庫中的ComboPooled。謝謝你的建議。

1

要獲得回滾時,拋出一個異常補充一點:

@Transactional(rollbackFor=Exception.class) 

您還需要建立transactionManger豆(這裏是我的,使用Hibernate):

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
       p:sessionFactory-ref="sessionFactory" /> 

我發現這tutorial信息。

+1

感謝您的答案,無論如何,我沒有使用Hibernate,只有普通的JDBC,我已經配置了我的TransactionManager(現在添加了問題中的代碼) – manub

+2

@Transactional回滾默認情況下,RuntimeExceptions,所以你需要指定僅當您想要在已檢查的異常上進行回滾時,或者您需要更精細的控制(例如,回滾自定義異常)時,才使用rollbackFor屬性。海報說這個方法拋出一個RuntimeException。 –

-2

我相信@Autowired和@Resource在@Component上不會被Spring掃描。 嘗試使用ContextHolder類來獲取上下文和DAO

@Component 
public class ContextHolder implements ApplicationContextAware { 

    /** 
    * Spring context which will directly be injected by Spring itself 
    */ 
    private static ApplicationContext context = null; 

    /** 
    * Overridden method of ApplicationContextAware, which will automatically be called by the container 
    */ 
    public void setApplicationContext(ApplicationContext context) throws BeansException { 
     this.context = context; 
    } 

    /** 

    /** 
    * Static method used to get the context 
    */ 
    public static ApplicationContext getApplicationContext() { 
     return context; 
    } 
} 

,並打電話給你的道:

ContextHolder.getApplicationContext().getBean("MyDAO"); 
+1

至少@Autowired註釋在使用@Component註釋的類上工作正常。我用過很多次。 –

+0

-1我還多次使用了@ @ Component和@ Autowired ... – Betlista