事務(wù)好渠,就是保證一系列業(yè)務(wù)邏輯全部執(zhí)行或者全部不執(zhí)行,在開發(fā)中节视,事務(wù)是怎么控制的呢拳锚?
方法一、使用hibernate的OpenSession()寻行。這種方式需要在業(yè)務(wù)邊界創(chuàng)建session霍掺,并將session作為參數(shù)傳遞到Dao層,以此來保證多個(gè)業(yè)務(wù)邏輯之間使用的是同一個(gè)session拌蜘。
添加用戶的同時(shí)要完成addLog()和addUser()兩個(gè)操作:
1. LogManagerImpl類中的添加日志
public void addLog(Log log杆烁,Session session){
session.save(log,session);
}
- UserManagerImpl類中完成所有業(yè)務(wù)邏輯
//openSession()創(chuàng)建session
SessionFactory factory= new Configuration().configure();
Session session=factory.openSession();
//開啟事務(wù)
session.beginTransaction();
//執(zhí)行業(yè)務(wù)邏輯1. 保存user
session.save(user);
//Log和LogManagerImpl的創(chuàng)建由IoC控制
log.setTime(new Date());
log.setType("操作日志");
//執(zhí)行業(yè)務(wù)邏輯2. 保存log,同時(shí)傳遞session
logManager.addLog(log,session);
session.getTransaction().commit();
//使用openSession拦坠,當(dāng)最后一個(gè)業(yè)務(wù)邏輯完成后必須關(guān)閉session
session.close();
方法二连躏、 使用Hibernate的getCurrentSession(),currentSession和openSession的區(qū)別在于贞滨,使用currentSession使用完畢后不用手動(dòng)關(guān)閉session入热。currentSession相當(dāng)于將session放到一個(gè)ThreadLocal中。
-
LogManagerImpl類
pubic void addLog(Log log){ //可以通過getCurrentSession()創(chuàng)建Session晓铆,不必使用傳遞的session Session session= factory.getCurrentSession() session.save(log); }
UserManagerImpl類中完成所有業(yè)務(wù)邏輯
//openSession()創(chuàng)建session
SessionFactory factory= new Configuration().configure();
Session session=factory.getCurrentSession();
//開啟事務(wù)
session.beginTransaction();
//執(zhí)行業(yè)務(wù)邏輯1. 保存user
session.save(user);
//Log和LogManagerImpl的創(chuàng)建由IoC控制
log.setTime(new Date());
log.setType("操作日志");
//執(zhí)行業(yè)務(wù)邏輯2. 保存log
logManager.addLog(log);
session.getTransaction().commit();
//使用currentSession勺良,當(dāng)最后一個(gè)業(yè)務(wù)邏輯完成后不用關(guān)閉session
- 使用currentSession,需要在hibernate.cfg.xml配置文件中開啟事務(wù)
<property name="hibernate.current_session_context_class">thread</property>
方案三骄噪、將hibernate和spring集成尚困,使用spring框架的聲明式事務(wù)。使用spring的聲明式事務(wù)链蕊,不再需要自動(dòng)創(chuàng)建sessionFactory和Session事甜,不再需要手動(dòng)控制事務(wù)的開啟和關(guān)閉。
使用spring聲明式事務(wù)的幾個(gè)步驟:
1. applicationContext.xml中進(jìn)行配置
<!-- 配置spring事務(wù)管理器-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="qq"></property>
</bean>
<!-- 配置spring事務(wù)滔韵,基于xml開發(fā)-->
<!-- 激活自動(dòng)代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!-- 配置aop -->
<aop:config>
<aop:pointcut expression="execution(* com.hw.service.impl.*.*(..))" id="pointcut"/>
<aop:advisor advice-ref="trcut" pointcut-ref="pointcut"/><!-- 增強(qiáng)切 -->
</aop:config>
<!-- 定義事務(wù)通知 -->
<tx:advice id="trcut" transaction-manager="transactionManager">
<!-- 定義事務(wù)傳播規(guī)則 -->
<tx:attributes>
<!-- REQUIRED的含義是支持當(dāng)前已經(jīng)存在的事務(wù),如果還沒有事務(wù)逻谦,就創(chuàng)建一個(gè)新事務(wù)
<tx:method name="*" propagation="REQUIRED"/>
表示所有方法都應(yīng)用REQUIRED事務(wù)規(guī)則-->
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>