hibernate3 更新数据问题,大家有碰到过的没?

jspxnet 2005-09-23 04:39:42
hibernate3 中我使用了二级缓存的.
数据库是oracle9i

<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

使用的是 ThreadLocal 方式.


DocBean thsDocPart = (DocBean)session.load(DocPart.class,id);
thsDocPart.setLogo("XXX变量每次不同");
thsDocPart.setLogoLink("XXX");
session.flush();

//-----------我使用了N种方法清空缓存
session.refresh(thsDocPart);
session.clear();
session.getSessionFactory().evict(DocPart.class);

问题:
第一次修改能够成功.后边的就不一定了.有时候成功了.但显示的是缓存的数据(没修改前的)
后边修改有时候能成功,有时候不成功.
我看了看显示的SQL,有时候 session.flush(); 并没有生成更新语句.
感觉很不稳定,而且缓存好像就清空不了.


...全文
208 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
jspxnet 2005-09-27
  • 打赏
  • 举报
回复
目前的网上通用的 ThreadLocal 方式实现, 在多线程交叉查询的时候并没有很处理.所以解决方法有
三个
1.不使用ThreadLocal 方式,用最基本的方式就可以了保证稳定了.
2.使用的时候不要出现多线程交叉查询,一般很难保证.
3.修改你的ThreadLocal 类.
java200408 2005-09-27
  • 打赏
  • 举报
回复
请问搂住是怎么解决的?
jspxnet 2005-09-26
  • 打赏
  • 举报
回复
终于碰到一个也有这个问题的朋友了.不过还有没有更好的解决方法,问题在那?
jspxnet 2005-09-26
  • 打赏
  • 举报
回复
<hibernate-mapping default-lazy="false">
<class name="jspx.jdoc.table.DocPart">
<id name="id" type="java.lang.String" length="50">
<generator class="uuid.hex" />
</id>
<property name="partId" type="java.lang.String" column="partId" length="100" not-null="true"/>
<property name="manId" type="java.lang.String" column="manId" length="50" not-null="true"/>
<property name="title" type="java.lang.String" column="title" length="50" not-null="true"/>
<property name="logo" type="java.lang.String" column="logo" length="200" not-null="false"/>
<property name="logoLink" type="java.lang.String" column="logoLink" length="200" not-null="false"/>
<property name="sortDate" type="java.util.Date" column="sortDate" not-null="true" />
</class>
</hibernate-mapping>
java200408 2005-09-26
  • 打赏
  • 举报
回复
这个问题我也碰到过。我的解决方案是:在查询时晴空session.而不是在进行修改时。
实例代码:
public List getCgList(Object searchObj, int currentPageNumb) {
List rtnList = new ArrayList();
try {
String sql = "from Phinfo as phinfo ";
sql = sql+getWhereSql(searchObj)+getOrderbySql();
Query query = this.getSession().createQuery(sql);
query.setFirstResult(DestributePage.perPageNumb * (currentPageNumb - 1));
query.setMaxResults(DestributePage.perPageNumb);
this.getSession().clear(); //晴空缓存
rtnList = query.list();
} catch (Exception ex) {
this.getLogger().error("____hibernate操作错误____", ex);
}
return rtnList;
}
  • 打赏
  • 举报
回复
在加没有打开二级缓存吧,不涉及到缓存同步。
或者是DocBean这个hbm的同步策略的问题,这个不太确定。
把DocBean.hbm贴出来吧。
jspxnet 2005-09-26
  • 打赏
  • 举报
回复
数据已经更新了的,但从cache 中读如老的数据后,又吧数据库的内容更新成老的了.
有时候更新SQL都没有.
我在家里电脑上测试了一下,写了个简单的更新,又没什么问题.就是公司的电脑上这个程序有这个问题.
奇怪啊
jspxnet 2005-09-26
  • 打赏
  • 举报
回复
终于知道问题了,是使用是 ThreadLocal 方式.的问题.
  • 打赏
  • 举报
回复
看看数据库里更新了没有?
  • 打赏
  • 举报
回复
请问:这些更新已经真正被持久化到表里了吗?
你可以试验一下来缩小问题的范围:

1,关闭Query_Chache, 因为修改数据时Query_Chache绝对没有意义。
2,关闭二级缓存。
批量更新:
for(...){
pojo = session.load(...)
session.update(pojo);
if( i%10 ==0 )
session.flush();
}
session.flush();
//这时再看看更新了没有?
jspxnet 2005-09-23
  • 打赏
  • 举报
回复
我换过其他的ECache 来用,效果一样,
感觉很奇怪,第一次更没问题.....
myth822 2005-09-23
  • 打赏
  • 举报
回复
那就不太清楚了,不好意思,不过hibernate不建议使用HashTable作为二级缓存,试试第三方的cache
jspxnet 2005-09-23
  • 打赏
  • 举报
回复
hibernate 步缓存策略 这个我不清楚
jspxnet 2005-09-23
  • 打赏
  • 举报
回复
另外我还加了个 default-lazy="false"
jspxnet 2005-09-23
  • 打赏
  • 举报
回复
<property name="hibernate.jdbc.use_streams_for_binary">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.transaction.auto_close_session">false</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property

其他都是默认的
myth822 2005-09-23
  • 打赏
  • 举报
回复
DocBean的同步缓存策略是什么?
jspxnet 2005-09-23
  • 打赏
  • 举报
回复
上边发错了点.
session.getSessionFactory().evict(DocBean.class);
我也用了的


session.refresh(DocBean);
session.clear();
session.getSessionFactory().evict(DocBean.class);

这几个方法我都用了的

myth822 2005-09-23
  • 打赏
  • 举报
回复
session.clear();是清空一级缓存的方法,楼主使用了二级缓存,二级缓存是SessionFactory级的所以要调用SessionFactory的evice()方法去清空

67,515

社区成员

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

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