大家好!今天项目中发现一个问题,希望大家帮忙!是用Hibernate + Spring 首先Session 是在非 OpenSessionInView 情况下。 // 此方法被配置事务传播特性为 NEVER
public void listtrans() {
List<Jobs> jobs = this.getHibernateTemplate().find("From Jobs");
for (Jobs job : jobs) {
try {
save(job);
} catch (Exception e) {
}
}
} // 此方法被配置事务传播特性为 REQUIRED
public void save(Jobs job) {
job.setMaxLvl(Short.valueOf("2"));
throw new RuntimeException("e");
}

可是这种情况下面当save异常的情况下,仍然会更新job.MaxLvl字段 , 也就是说Hibernate仍然进行了脏数据检查,并且更新,(但是脏数据检查应该出现在Commit 之前吧? 而listtrans方法中并没有事务存在),  但是当listtrans传播特性设置为read-only或者是根本不配置它的传播特性的时候。 则不会更新job.MaxLvl字段 也就是说不会进行脏数据检查了。情况就是这样,  但是我想知道为什么会这样! 

解决方案 »

  1.   

     // 此方法被配置事务传播特性为 NEVER
        public void listtrans() {
            List<Jobs> jobs = this.getHibernateTemplate().find("From Jobs");
            for (Jobs job : jobs) {
                try {
                    save(job);    
                } catch (Exception e) {
                }
            }
        }
    这里明显存在事物,你定义为 NEVER,不报错才怪
      

  2.   

    楼主,不知道你说的结果是否真得测试过。反正我第一眼看到你的题目感觉你这问题本身就有错误。
    我知道你的意思,现在我把我的思路给你说下,看能不能满足你的要求。
    你在listtrans()方法中将事务的级别设为NERVER,此时表示这个方法只能在没有事务的环境中运行,这对于查询操作来说没有任何的问题,当把数据查询出来后,调用save()方法,更新一些属性,你将save()方法设置成REQUIRED,即在没有事务的情况下会创建一个新的事务,在有事务的情况下就加入此事务,而此时调用的save()方法的上下文没有事务,因此会新创建一个事务,执行更新操作,由于查询时没有启动事务,也就是查询和更新两个操作没有共享一个session,因此更新应该不会成功。(当设置成NEVER时,只是调用该方法的上下文不能有事务,并不代表方法内部不能创建一个新的事务,大伙觉得这话正确吗?反正我测试时故意用REQUIRED_NEW,发现程序可以正常通过)
    当listtrans传播特性设置为read-only时,此时是只读事务,save()也会加入到此事务中,但是这个事务是只读事务,因此也不会更新数据库的操作,只是查询出来的User对象改变而已。
    当listtrans传播特性设置为不配置的时候,也就是没有事务的存在,查询的时候没有事务,之后调用save()也只是更新了User对象,不会改变数据库的数据。
    只是个人意见,仅供参考。
      

  3.   


    谢谢你的回答, 但是现在的情况确实是如果使用NEVER两个方法公用Session,其他两种情况则不会。 代码肯定是测试过的。