采用编程式事务
程序示例:
1、以前单个事物的控制
1)HibernateUtils 工具类
package com.bjsxt.usermgr.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtils { private static SessionFactory factory; static { try { Configuration cfg = new Configuration().configure(); factory = cfg.buildSessionFactory(); }catch(Exception e) { e.printStackTrace(); } } public static SessionFactory getSessionFactory() { return factory; } public static Session getSession() { return factory.openSession(); } public static void closeSession(Session session) { if (session != null) { if (session.isOpen()) { session.close(); } } } }
2)UserManagerImpl 单个user存储中使用事务
package com.bjsxt.usermgr.manager; import java.util.Date; import org.hibernate.Session; import com.bjsxt.usermgr.model.Log; import com.bjsxt.usermgr.model.User; import com.bjsxt.usermgr.util.HibernateUtils; public class UserManagerImpl implements UserManager { public void addUser(User user) { Session session = null; try { session = HibernateUtils.getSession(); //session = HibernateUtils.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.save(user); Log log = new Log(); log.setType("安全日志"); log.setDetail("xxx进入系统"); log.setTime(new Date()); LogManager logManager = new LogManagerImpl(); logManager.addLog(log); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } }
2、现在需要对保存用户和日志当作一个事务同时处理
按以前的方法,我在保存日志时需要把user的当前session也一起传递过去
现在hebernater3.0以后可以用以下方法:
package com.bjsxt.usermgr.manager; import java.util.Date; import org.hibernate.Session; import com.bjsxt.usermgr.model.Log; import com.bjsxt.usermgr.model.User; import com.bjsxt.usermgr.util.HibernateUtils; public class UserManagerImpl implements UserManager { public void addUser(User user) { Session session = null; try { //session = HibernateUtils.getSession(); session = HibernateUtils.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.save(user); //事物有效性测试,制造异常:Integer.parseInt("asdfsdfsfsd"); Log log = new Log(); log.setType("安全日志"); log.setDetail("xxx进入系统"); log.setTime(new Date()); LogManager logManager = new LogManagerImpl(); logManager.addLog(log); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); // }finally { // HibernateUtils.closeSession(session); } } }
3、以上代码中getCurrentSession()与openSession()的区别?
* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
创建的session必须手动关闭
4、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)--->即只有一种数据库的情形
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)----->即即有多个数据库或还有资源文件,需要将配置文件改为
<property name="hibernate.current_session_context_class">jta</property>