Hibernate 的Session flush设计是否有问题?

m99c 2005-04-27 10:03:40
1。在session1中加载一persistent object(比如订单对象Order),然后修改此persistent object,再session1调用flush把更改的数据发送到数据库。
2。在session2加载上面的对象,此时得到的是上面已更改的对象。
3。在session1打开的transaction 调用rollback,此时数据库又恢复成原来的对象。但session2得到的数据是不同步的,可能会引起很多问题。
请问flush设计是否有问题?有没有其他方法可以避免?
下面是我的Junit test代码,测试是通过的。

public void testFlush() {

Session sess1 = openSession();

//Load a sales order from session1
SalesOrder order1 = null;
Criteria q = sess1.createCriteria(SalesOrder.class);
q.setFirstResult(0);
q.setMaxResults(1);
List orders = q.list();
for (Iterator iter = orders.iterator(); iter.hasNext();) {
order1 = (SalesOrder) iter.next();
}

//Modify sales order's buyer
String oldBuyer = order1.getBuyer();
String newBuyer = "vvv";
order1.setBuyer(newBuyer);

//Flush session1,send sql statement to database
Transaction transaction = sess1.beginTransaction();
sess1.flush();

//Open session2 to load current sales order
Session sess2 = openSession();
SalesOrder order2 = (SalesOrder) sess2.load(SalesOrder.class, order1
.getId());
assertEquals(order2.getBuyer(), newBuyer);
//order is changed in database
sess2.close();

//Roll back,lose all change.
transaction.rollback();
sess1.close();


Session sess3 = openSession();
SalesOrder order3 = (SalesOrder) sess3.load(SalesOrder.class, order1
.getId());
assertEquals(order3.getBuyer(), oldBuyer);

}
...全文
149 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
m99c 2005-04-28
  • 打赏
  • 举报
回复
在我的例子中是直接调用Session.flush(),按Hibernate文档的说法,在某些查询执行时也会自动调用flush,这就有潜在的不安全。除非我指定sess.setFlushMode(FlushMode.COMMIT),每次transction commit时才flush,但这样Hibernate的API就没有必要存在flush()方法。

Hibernate的文档:
flush, occurs by default at the following points

1.before some query executions

2.from org.hibernate.Transaction.commit()

3.from Session.flush()

benjamin_von 2005-04-28
  • 打赏
  • 举报
回复
不知道我有没有理解楼上的意思:

在某些查询执行时也会自动调用flush不会造成脏数据阿,所以不会有潜在的不安全阿。
所有会造成数据不同步的情况,例如你所提到的,都应该避免。举个例子,数据库的2阶段提交肯定要保证都提交成功,或者都失败。不可能把成功一半的数据暴露给其他用户的。
benjamin_von 2005-04-27
  • 打赏
  • 举报
回复
楼主说的没有错,的确是不同步的。 但这个也就是为什么需要transaction的原因阿,这个transaction要么成功提交,要么rollback,这样才能保证后续程序取得的数据与数据库中的数据同步阿。

其实数据库也是这么实现的,一段数据库操作,要么commit,要么rollback,而中间的结果是不允许访问的。也就是说session1所在transaction操作过程的中间数据是不可以被session2访问的。必须要是线程安全的。

67,513

社区成员

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

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