一、环境
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;