Spring整合hibernate关于控制事务的问题

本文分析了在Spring整合Hibernate框架中,控制事务时遇到的数据更新未取到最新数据的问题。详细解释了由于Hibernate缓存机制导致的问题原因,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在使用spring整合hibernate的框架中控制事务遇到数据更新未取到最新的数据,代码结构如下:
注:此处调用查询方法定义为query(),
调用更新方法定义为update(),
调用执行sql的方法定义为execute();
TableObject 对应表 dataTable;
汇总表对应 totalDataTable;

/**
*a方法循环调用b方法
*/
public void a(){ //事务控制层
    List<String> priNumbers = new ArrayList<String>();
    priNumbers.add("1");
    priNumbers.add("2");
    priNumbers.add("3");
    //循环修改dataTable的值
    for(String priNumber : priNumbers ){
        b(priNumber);
    }

    //根据dataTable的最新值修改totalDataTable的汇总值
    c();
}
/**
*b方法查询对象并更新对象
*/
public void b(String priNumber){ 
    //根据主键查询数据库表对象obj
    TableObject obj = query(priNumber);
    .
    .
    .//修改obj的值,此处省略

    //更新obj值
    update(obj);
}

/**
*c方法执行sql根据数据库表dataTable中的最新数据所有值之和修改汇总表totalDataTable的数据
*/
public void c(){
    execute(sql);
}

在执行上述代码后,totalDataTable表中的数据总是取的是前两次更新后数据和最后一次未更新的数据值的汇总值,原因是:
事务控制在a()方法层因此事务提交是在a()方法结束时再调用commit()方法,而hibernate机制是在事务提交时才调用flush()方法将持久化对象同步到数据库,在此之前,该持久化对象是存在缓存中的,因此在b方法中执行update时数据库中的数据是没有同步的,所以我们会读取到最后一次未更新的数据值,但是为什么前两次更新后的数据是数据库的最新值呢?这是因为hibernate的缓存中只能存在一个同一类型的持久化对象,在我们调用query()方法时,hibernate就会将上一次的保存在缓存中的持久化对象flush到数据库同步,并更新缓存中的持久化对象。
解决方法:因为我们要取到数据必须是数据库最新的值,因此我们需要在调用hibernate的save()、update()、saveOrUpdate()方法后手动的调用一次flush()方法,使缓存数据与数据库数据同步。
注:如果我们不添加事务,实际是不会出现以上问题的,因为未加事务时,hibernate默认事务提交是在dao层方法调用结束后调用flush()和commit()方法,而正是因为我们添加了事务,导致hibernate调用flush()和commit()延迟到我们控制的事务结束时,这时执行的数据库更新操作如果没有调用flush()操作实际是存在缓存中而并没有和数据库同步的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值