用hibernate的getcurrentsession() 造成了数据库和查询的不同步,是怎么回事?
getcurrentsession()和opensession()用法有什么区别?我现在在改一个系统的bug,这个系统中有的地方这样获取session:getcurren...
getcurrentsession()和opensession() 用法有什么区别?我现在在改一个系统的bug,这个系统中有的地方这样获取session:getcurrentsession() 并update数据,但是会出现这种情况:已经更新完了(数据库里也更新了),但是 在查询时查到的仍然是更新之前的数据,但是把getcurrentsession()替换成opensession()就没问题了,这是怎么回事 ?我知道opensession()可以暂时性的把问题解决,但是又怕出现问题?比如线程是不是安全,因为很多人会同时用这个系统!
展开
3个回答
展开全部
我个人觉得是你这里的getcurrentsession没有提交事务,导致执行了更新操作 但实际底层没有提交事务,意思就是说最终没有进行commit 而不是你说的线程延迟什么问题。
getcurrentsession()和opensession() 的区别重点不是在于线程问题,而是管理事务回滚问题。
比如你用getcurrentsession取了当前session,当你循环List<Object>对象并更新每个对象里的一个字段时报了错误,那很多项目中根据公司需求得进行回滚,比如回滚整个List对象,或者回滚当前这一个对象并继续更新下一个对象等。当你用当前session了说明你的每个对象对应的每个事物都被一个session管理,而用了opensession说明你的每个对象每次开启了新session 不但占用了很多资源,而且每个session对应一个事务。大多数情况都是封装用getcurrentsession因为每次逻辑都用一个session来管理 也不占资源。
每次取session时候底层都用的是sessio。load方法,这个方法 就跟hibernate懒惰加载有关系,就比如楼上说的改成lazy=false 但这个也不建议改,如果用了lazy=false了说明勤奋加载 那样程序负担太大。
自从用了spring开始,线程安全,同步都归spring的ThreadLocal管理,用的是临时线程变量机制,一般不会出现并发报错问题。
希望对你有所帮助
getcurrentsession()和opensession() 的区别重点不是在于线程问题,而是管理事务回滚问题。
比如你用getcurrentsession取了当前session,当你循环List<Object>对象并更新每个对象里的一个字段时报了错误,那很多项目中根据公司需求得进行回滚,比如回滚整个List对象,或者回滚当前这一个对象并继续更新下一个对象等。当你用当前session了说明你的每个对象对应的每个事物都被一个session管理,而用了opensession说明你的每个对象每次开启了新session 不但占用了很多资源,而且每个session对应一个事务。大多数情况都是封装用getcurrentsession因为每次逻辑都用一个session来管理 也不占资源。
每次取session时候底层都用的是sessio。load方法,这个方法 就跟hibernate懒惰加载有关系,就比如楼上说的改成lazy=false 但这个也不建议改,如果用了lazy=false了说明勤奋加载 那样程序负担太大。
自从用了spring开始,线程安全,同步都归spring的ThreadLocal管理,用的是临时线程变量机制,一般不会出现并发报错问题。
希望对你有所帮助
追问
不好意思,我写反了,是这样:update数据时用的opensession 并commit,而查询时用的getcurrentsession(),没用commit (个人感觉查询是不用commit的吧),照这样的话应该解释呢?非常感谢!!
追答
首先得明白后台什么时候执行sql的update语句。当你调用save或者update方法时候底层不会直接给你执行update语句,直到session。flush时候清理缓存 并执行sql(你可以在修改hibernate配置,显示sql语句),然后进行commit,而commit主要目的是对事物的回滚,至于查询没什么作用,如果更新操作中你也不想对其回滚也可以不写commit,但session。flush得必须写,而现在我们一般不写session。flush方法是因为hibernate在执行commit方法之前默认调用flush所以我们以为是commit后才发出SQL。
而至于你写反了的意思是 先用opensession update了,并用getcurrentSession查询时候查出以前的数据吗?那你更改了哪个又好使了?有点没看懂
按正常逻辑 是得先用opensession 并用这个session。update,commit后 再调用currentSession查询不应该显示之前的数据。但要是你程序在更新时候报错了 会回滚,那查出的就是以前的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
把cfg.xml配置表中的表属性加上lazy=false
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询