一、环境
SSH环境,查询用的是基于Hibernate的配置文件构建了一个SessionFactory,主要代码如下
public class HibernateUtil { private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = null; public static SessionFactory sessionFactory; static { try { configuration = new Configuration().configure("/hibernate.cfg.xml"); sessionFactory = configuration.buildSessionFactory(); } catch (HibernateException e) { System.out.println("解析xml和创建Session工厂error"); e.printStackTrace(); } } public static Session getSession() { Session session = threadLocal.get(); if (session == null) { session = sessionFactory.openSession(); threadLocal.set(session); } //Session session=sessionFactory.getCurrentSession(); return session; } // ThreadLocal可以隔离多个线程的数据共享,因此不再需要对线程同步 public static final ThreadLocal<Session> session = new ThreadLocal<Session>(); //创建Session public static Session currentSession() throws HibernateException { //通过线程对象.get()方法安全创建Session Session s = session.get(); // 如果该线程还没有Session,则创建一个新的Session if (s == null) { s = sessionFactory.openSession(); // 将获得的Session变量存储在ThreadLocal变量session里 session.set(s); } return s; } //关闭Session public static void closeSession() throws HibernateException { Session s = session.get(); if (s != null) s.close(); session.set(null); } }
二、问题
之后在具体业务中对该工具类引用,代码如下
public Map<String, List<UserTempDto>> packetStatistics(Map<String, String> params) { System.out.println("99999999999999999999999999"); Map<String, List<UserTempDto>> map = new HashMap<String, List<UserTempDto>>(); List<UserTempDto> userTypeList = new ArrayList<UserTempDto>(); List<UserTempDto> provinceList = new ArrayList<UserTempDto>(); String serachCondition = serachCondition(params); serachCondition=StringUtils.isBlank(serachCondition)? "":serachCondition; //��ȡsession Session session=HibernateUtil.getSession(); //����ʡ�ݷ���hql String groupByProvince = " group by province"; String hqlCountProvince = "select province,COUNT(user_code) FROM StatUserinfo where 1=1 "; Query countProvince = session.createQuery(hqlCountProvince+serachCondition+groupByProvince); @SuppressWarnings({ "unchecked", "unused" }) List<Object[]> countProvinceList=(List<Object[]>)countProvince.list(); //����רί�����hql String groupByUserType = " group by userType"; String hqlCountUserType = "select userType,COUNT(user_code) FROM StatUserinfo where 1=1 "; Query countUserType = session.createQuery(hqlCountUserType+serachCondition+groupByUserType); List<Object[]> countUserTypeList=(List<Object[]>)countUserType.list(); HibernateUtil.closeSession(); UserTempDto userTempDto; try { for (Object[] objects : countUserTypeList) {//����רί�����ͳ�� String userType=(String) objects[0]==null? "未知":(String)objects[0]; Long cUserType=(Long) objects[1]; userTempDto=new UserTempDto(); userTempDto.setCountUserType(cUserType); userTempDto.setUserType(userType); userTypeList.add(userTempDto); } for (Object[] objects : countProvinceList) {//����רί�����ͳ�� String province=(String) objects[0]==null? "未知":(String)objects[0]; Long cProvince=(Long) objects[1]; userTempDto=new UserTempDto(); userTempDto.setProvince(province); userTempDto.setCountProvince(cProvince); provinceList.add(userTempDto); System.out.println("省份:"+province+"&人数:"+cProvince); } } catch (Exception e) { e.printStackTrace(); } map.put("userTypeList", userTypeList); map.put("provinceList", provinceList); return map; }
但是 每次tomcat启动后 第一次查询是正确的 ,然后做修改操作,第二次查询就不正确了,查询不到修改后的数据,必须重启tomcat,才可以查询到和数据库最新数据一样的数据
三、解决办法
想到了缓存,但是项目中hibernate.cfg.xml根本没有使用缓存,因为没有相关的配置。也更改了Session的获取类型,比如
session = sessionFactory.openSession();
替换为
Session session=sessionFactory.getCurrentSession();
都没有起到什么作用
关键的来了!
Session session=HibernateUtil.getSession();
//by wxj
Transaction tx=session.beginTransaction();
//����ʡ�ݷ���hql
String groupByProvince = " group by province";
String hqlCountProvince = "select province,COUNT(user_code) FROM StatUserinfo where 1=1 ";
Query countProvince = session.createQuery(hqlCountProvince+serachCondition+groupByProvince);
@SuppressWarnings({ "unchecked", "unused" })
List<Object[]> countProvinceList=(List<Object[]>)countProvince.list();
//����רί�����hql
String groupByUserType = " group by userType";
String hqlCountUserType = "select userType,COUNT(user_code) FROM StatUserinfo where 1=1 ";
Query countUserType = session.createQuery(hqlCountUserType+serachCondition+groupByUserType);
List<Object[]> countUserTypeList=(List<Object[]>)countUserType.list();
//by wxj
tx.commit();
在查询之前,还有查询结束之后分别增加了 开始事务和提交事务的操作,数据奇迹的发生了变化,tomcat启动后,查询数据台湾省有1个用户,接着修改一个用户的归属为台湾省
此时数据库中有两个用户是台湾省了,再次查询数据,台湾省的用户为2,即修改操作和查询操作数据同步了
需要注意的是 事务是hibernate的事务
import org.hibernate.Transaction;