2014-02-06 41 views
0

我在Spring中的事務沒有啓動時出現問題,因此對數據庫所做的更改未保存。配置如下:事務未啓動Spring + Hibernate + MySQL

web.xml文件(沒有的DispatcherServlet,有FacesServlet的)

<context-param> 
    <param-name>contextConfigLocation</param-name> 
<param-value>classpath:applicationContext.xml</param-value> 
</context-param> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

從applicationContext.xml中相關的配置是這樣的:

<context:annotation-config /> 
<context:component-scan base-package="pl.web.beans,pl.csci.dao" /> 

<bean id="sessionFactoryCsci" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> 
    <property name="configLocation" value="classpath:csci_database.cfg.xml" /> 
</bean> 

<bean id="hibernateTemplateCsci" class="org.springframework.orm.hibernate3.HibernateTemplate"> 
    <property name="sessionFactory"> 
     <ref bean="sessionFactoryCsci" /> 
    </property> 
</bean> 

<bean id="hibernateDaoSupportCsci" class="org.springframework.orm.hibernate3.support.HibernateDaoSupport" abstract="true"> 
    <property name="hibernateTemplate" ref="hibernateTemplateCsci" /> 
</bean> 

<bean id="csciPermSystemDAO" class="pl.csci.dao.CsciPermSystemDAO" parent="hibernateDaoSupportCsci"> 
</bean> 

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

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

最後類負責用於保存實體:

pl.csci.dao 
@Transactional(readOnly = true) 
public class CsciPermSystemDAO extends HibernateDaoSupport implements ICsciPermSystemDAO { 
@Override 
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
public Integer addPermission(Permissions Permission) throws DaoException { 
    try { 
     Integer permissionId = (Integer) getHibernateTemplate().save(Permission); 
     LOGGER.info("Is transaction active?:" + DebugUtils.transactionActive()); 
     return permissionId; 
    } catch (Throwable ex) { 
     // exception handling 
    } 
} 

上面的代碼片段(Deb ugUtils.transactionActive())返回false。此方法使用TransactionSynchronizationManager類來確定事務是否處於活動狀態。

調試時休眠,我可以看到插入記錄,但這些刀片實際上可以永遠不會出現在數據庫:

2014年1月30日15時13分15秒DEBUG [hibernate.SQL] - 插入csci_perm。權限(BRANCH,GROUP_ID,PERSON_ID,READ_PERM,SYSTEM_ID,WRITE_PERM)值(?,?,?,?,?,?)

請問我的配置有什麼問題?

最後,這裏是Hibernate的配置:

<hibernate-configuration> 
    <session-factory> 
    <!-- Database connection settings --> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/csci_perm</property> 
    <property name="hibernate.connection.useUnicode">true</property> 
    <property name="hibernate.connection.characterEncoding">utf8</property> 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
    <property name="hibernate.connection.username">user</property> 
    <property name="hibernate.connection.password">password</property> 
    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 
    <property name="c3p0.acquire_increment">1</property> 
    <property name="c3p0.idle_test_period">3000</property> 
    <!-- seconds --> 
    <property name="c3p0.max_size">20</property> 
    <property name="c3p0.max_statements">50</property> 
    <property name="c3p0.min_size">3</property> 
    <property name="c3p0.timeout">100</property> 
    <!-- seconds --> 
    <!-- Enable Hibernate's automatic session context management --> 
    <property name="current_session_context_class">thread</property> 
    <!-- Disable the second-level cache --> 
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 
    <!-- Echo all executed SQL to stdout - You can disable this once you have it working --> 
    <property name="show_sql">true</property> 
    <property name="hibernate.jdbc.batch_size">10</property> 
    <mapping class="pl.csci.model.Permissions"/> 
    </session-factory> 
</hibernate-configuration> 
+0

你如何定義你的TransactionManager? – WeMakeSoftware

+0

我編輯了第一篇文章 – Jarek

回答

0

這可能是因爲數據庫不支持事務。

檢查此document

MySQL服務器(版本3.23-max和所有版本4.0及以上版本)支持與InnoDB和BDB事務存儲引擎的交易。

+0

我運行命令'show table status;'在MySQL數據庫上,它顯示使用InnoDB引擎。另外,當我運行'show engines'命令時,我可以看到InnoDB默認使用,似乎啓用了事務。 – Jarek

0

您的配置錯誤,使用彈簧時千萬不要亂用current_session_context_class,除非您使用的是JTA。將其設置爲線程禁用會彈出適當的事務管理。

接下來你的代碼也在破壞正確的事務管理,從來沒有發現併吞下預期,這樣transactionamangement失敗了,因爲它永遠不會看到異常,並會嘗試提交。要麼抓住並重新拋出,要麼不抓住。

最後,您不應該使用HibenateDaoSupport和/或HibernateTemplate,這些應該在Hibernate 3.0.1(2006年左右)時被視爲棄用。如解釋here直接使用SessionFactory

基本上你的刀應該是這樣的

@Transactional(readOnly = true) 
public class CsciPermSystemDAO implements ICsciPermSystemDAO { 

    private SessionFactory sf; 

    @Override 
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
    public Integer addPermission(Permissions Permission) throws DaoException { 
     LOGGER.info("Is transaction active?:" + DebugUtils.transactionActive()); 
     return (Integer) sf.getCurrentSession().save(permission); 
    } 

    public void setSessionFactory(SessionFactory sf) { 
     this.sf=sf; 
    } 
} 

另一個提示你hibernate.cfg.xml文件的hibernate.connectionc3p0性質是無用的。您正在注入一個數據源,這些屬性僅在hibernate管理數據源/連接時使用。

關於您的彈簧配置<context:annotation-config />已暗示<context:component-scan />。在會話 - 工廠配置中,您將設置org.hibernate.cfg.AnnotationConfiguration刪除此設置,而改爲使用AnnotationSessionFactoryBean而不是LocalSessionFactoryBean。這爲你節省了一些XML。

相關問題