网站运维之JAVA-SSH框架数据同步问题

时间:2023-03-10 07:21:01
网站运维之JAVA-SSH框架数据同步问题

一、环境

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;