<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!-- 配置數據源 Hibernate支持 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="username" value="scott" /> <property name="password" value="tiger" /> <property name="url" value="jdbc:oracle:thin:@localhost:1521:myorcl" /> </bean> <!-- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">--> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" > <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.Oracle9Dialect </prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop> </props> </property> <property name="mappingResources"> <list> <value>com/neusoft/leehom/model/Emp.hbm.xml</value> <value>com/neusoft/leehom/model/Dept.hbm.xml</value> </list> </property> </bean> <!-- 事務管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 配置那些類的方法進行事務管理,須要aopalliance-1.0.jar和aspectjweaver.jar,當前com.neusoft.leehom.service包中的子包, 類中全部方法須要,還須要參考tx:advice的設置 --> <!-- 須要引入tx的命名空間 --> <!-- 這是事務通知操做,使用的事務管理器引用自 transactionManager --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 指定哪些方法須要加入事務,這裏懶惰一下所有加入,能夠使用通配符來只加入須要的方法 --> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true"/> <tx:method name="query*" propagation="REQUIRED" read-only="true"/> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <!-- 須要引入aop的命名空間 --> <aop:config> <!-- 切入點指明瞭在執行Service的全部方法時產生事務攔截操做 --> <aop:pointcut id="daoMethods" expression="execution(* com.neusoft.leehom.service.impl.*.*(..))" /> <!-- 定義了將採用何種攔截操做,這裏引用到 txAdvice --> <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods" /> </aop:config> </beans>
配置事務時應該加載aopalliance-1.0.jar和aspectjweaver.jar這兩個包,這兩個包是必須的。覺得這樣就能夠對事務進行控制了,可是沒有想到在測試的時候發現dao層中的save、delete等方法都不能進行持久化。最終發現是取到的session不能爲sessionFactory.openSession(),而是應該爲sessionFactory.getCurrentSession().同時應該在配置爲文件中的propagation傳播方式最好爲required。這是由於當有一個方法list 傳播行爲爲Supports,當在另外一個方法getPage()(無事務)調用list方法時會拋出org.hibernate.HibernateException: No Session found for current thread 異常。java
根本緣由是getCurrentSession()在沒有session的狀況下不會自動建立一個,所以最好的解決方案是使用REQUIRED的傳播行爲。spring
如今知道事務的配置了,下面來看一下怎麼使用事務管理。sql
dao層部分代碼:express
package com.neusoft.leehom.dao; public class EmpDAO { private static final Logger log = LoggerFactory.getLogger(EmpDAO.class); // property constants public static final String ENAME = "ename"; public static final String JOB = "job"; public static final String MGR = "mgr"; public static final String SAL = "sal"; public static final String COMM = "comm"; private SessionFactory sessionFactory; public Session getSession() { return sessionFactory.getCurrentSession(); } public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void save(Emp transientInstance) { log.debug("saving Emp instance"); try { Session session = getSession(); session.save(transientInstance); log.debug("save successful"); } catch (RuntimeException re) { log.error("save failed", re); throw re; } } public void delete(Emp persistentInstance) { log.debug("deleting Emp instance"); try { Session session = getSession(); session.delete(persistentInstance); log.debug("delete successful"); } catch (RuntimeException re) { log.error("delete failed", re); throw re; } } .......... }
service層部分代碼:apache
package com.neusoft.leehom.service.impl; public class EmpManagerImpl implements IEmpManager { private EmpDAO empDao; /** * 查詢全部的數據信息 */ public List queryAll() { return empDao.findAll(); } /** * 插入數據 */ public void insertEmp(Emp emp){ empDao.save(emp); } /** * 刪除數據 */ public void deleteEmp(short id) { Emp emp = empDao.findById(id); empDao.delete(emp); } public void setEmpDao(EmpDAO empDao) { this.empDao = empDao; } ....... }