一、环境
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>();//创建Sessionpublic static Session currentSession()throws HibernateException{//通过线程对象.get()方法安全创建SessionSession s = session.get();// 如果该线程还没有Session,则创建一个新的Sessionif (s == null){s = sessionFactory.openSession();// 将获得的Session变量存储在ThreadLocal变量session里 session.set(s);}return s;}//关闭Sessionpublic 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;//��ȡsessionSession session=HibernateUtil.getSession();//����ʡ�ݷ���hqlString 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();//����רί�����hqlString 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;