采用编程式事务
程序示例:
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>