spring + hibernate 脏读数据问题,跪求各路高手给个答案

cxks22 2012-03-31 06:15:20
直接上代码。
ClassA{
updateA(){
updateAthao()

// 调用B的save
ClassB.saveB();
// 调用C的save
ClassC.saveC();
}
updateAthao(){
// 修改表数据
}

}

ClassB{
saveB(){
// 其它修改操作
for (){
查询表B
修改表B
}
}
}

ClassC{
saveC(){
throw Exception();
}
}

action类调用ClassA.saveA()。
ClassB.saveB多次查询并修改表B的数据。
当ClassC.saveC()抛出异常时,ClassA.updateAthao()中修改的数据全部回滚。
ClassB.saveB()中只有循环中最后一次修改的数据回滚,其它全部提交

经过调试后发现这是因为hibernate为避免出现脏数据,所以在查询后修改数据再查询同一表的数据时会将之前的事务全部提交。

有一个办法可以解决就是查询不在循环中进行,只要先查询后修改,就不会有问题。
但是这个方法不太好,有没有办法让循环中的操作也和其它修改一样和ClassA中的操作一起回滚呢。
...全文
341 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
cxks22 2012-04-01
  • 打赏
  • 举报
回复
dao 层没有配事务
昨日凡阳 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

没试过,不过应该 是可以的
[/Quote]

我觉得跟那个没有关系,本身从数据库查询出来的都是持久状态的。
是否有必要再转成游离状态,是需要评估一下。不过,你再从事物的角度去看看,特别是dao层的事物。
cxks22 2012-03-31
  • 打赏
  • 举报
回复
没试过,不过应该 是可以的
昨日凡阳 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

又找到一种方法就是将查询出来的对象转化脱管态再操作就没有问题,就是不知道能不能配置对象只在dao层是持久态
[/Quote]

瞬时态 (Transient)、持久态(Persistent)、脱管态(Detached)

那瞬时态也就是ok的?
cxks22 2012-03-31
  • 打赏
  • 举报
回复
又找到一种方法就是将查询出来的对象转化脱管态再操作就没有问题,就是不知道能不能配置对象只在dao层是持久态
昨日凡阳 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

没有说清楚,这里写的就是service层的操作,
action类调用classA.updataA();updataA调用ClassB.savaB()和ClassC.savaC().
[/Quote]

你要给dao 和 service层都加上事物。savaB中,确保可以正常回退
cxks22 2012-03-31
  • 打赏
  • 举报
回复
没有说清楚,这里写的就是service层的操作,
action类调用classA.updataA();updataA调用ClassB.savaB()和ClassC.savaC().
昨日凡阳 2012-03-31
  • 打赏
  • 举报
回复
1、你上面写的乱哄哄的,只看到了updateA,没有看到saveA。
2、我不知道你saveB中是如何循环与db交互的,就比如,你查询一笔,修改一笔。saveB整个应该算是2个原子操作吧。这是dao层的,你dao层首先加上事物,然后,在一个方法中操作多个原子操作的时候,确保一个成功后,再执行下一个,并且,如果是循环的存取,应该设置一个标记flag,除非所有saveB都执行ok,flag = true,否则,只要有一笔失败,全部失败。这样,就到了service层,service层加上了事物。同样,对于数据库的多个原子操作,也类似这样的做法。这样应该就不会出现脏数据。如果有可能出现,那也应该是多线程情况下出现的。
cxks22 2012-03-31
  • 打赏
  • 举报
回复
我的事务配置如下:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>


<!-- 配置事务的传播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="change*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="create*" propagation="REQUIRED"/>
<tx:method name="audit*" propagation="REQUIRED"/>
<tx:method name="init*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

数据库是mysql

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧