青岛达内吧 关注:46贴子:981
  • 2回复贴,共1

对象标识的范围

只看楼主收藏回复

对象标识的范围
作为应用程序开发者,我们使用Java对象标识(a=b)来标识对象。因此,如果对象改变了状态,那么能够保证在新的状态中它的Java 标识仍然相同么?在分层的应用程序中可能不会这样。为了研究这个话题,有必要理解Java标识a=b 与数据库标识a.getId().equals( b.getId() )之间的关系。有时它们是相等的,有时却不相等。我们把Java 标识等于数据库标识的情况称为对象标识范围(scope of object identity)。在这个范围内,通常有三种选择:l 没有标识范围(no identity scope)的简单持久层不能保证如果某一行被访问两次,应用程序能够返回相同的Java 对象实例。如果应用程序在一个单独的事务中修改了代表相同行的两个不同的实例将会出问题(你怎样决定哪一个状态将会同数据库同步?)。l 使用事务范围标识(transaction-scoped identity)的持久层保证在单独的事务上下文中,仅仅有一个对象实例代表数据库中的某一行。这就避免了前面那个问题,并且允许做一些事务级的缓存。l 过程范围标识(process-scoped identity)更进一步,它能保证在整个过程(JVM)中只有一个对象实例代表某一行。对于典型的网络或企业应用程序,事务范围标识是首选的。过程范围标识在利用缓存和多个事务重用实例的编程模型方面有一些潜在的优点;然而在普遍的多线程应用程序中,同步共享访问全局标识图中的持久对象要花费很大代价。在每个事务范围内每个线程只同完全不同的一组持久实例工作将会更加简单、更易于升级。宽松地讲,Hibernate执行事务范围的标识。实际上,Hibernate 标识范围是Session的实例,如果对象在几个操作中使用相同的持久管理器(the Session)就能够保证这些对象是相等的。但是Session同(数据库)事务是不一样的—它是一个更复杂的元素。我们将会在下一章探索Hibernate In Action 中文版Java爱好者http://www.JavaFan.NET 制作这个概念的不同及结果。让我们再次关注持久化生命周期和标识范围。如果你在同一个Session中使用相同的数据库标识符值请求两个对象,结果将会是对同一个内存对象的两个引用。下面的代码示例在两个Session中用几个load()操作演示这种行为:Session session1 = sessions.openSession();Transaction tx1 = session1.beginTransaction();// Load Category with identifier value "1234"Object a = session1.load(Category.class, new Long(1234) );Object b = session1.load(Category.class, new Long(1234) );if ( a==b ) {System.out.println("a and b are identical.");}tx1.commit();session1.close();Session session2 = sessions.openSession();Transaction tx2 = session2.beginTransaction();Object b2 = session2.load(Category.class, new Long(1234) );if ( a!=b2 ) {System.out.println("a and b2 are not identical.");}tx2.commit();session2.close();由于对象引用a和b 在相同的Session中装载,它们不仅有相同的数据库标识,而且有相同的Java标识。然而,一旦超出了这种界限,Hibernate 就不能保证Java 标识是相等的,因此,a 和b2 是不相等的,信息打印在控制台上。当然,测试数据库标识--a.getId().equals( b2.getId() )—将仍然返回true。为了更深入讨论标识范围,我们需要考虑持久层怎样持有对标识范围外的对象的引用。例如,对于像Hibernate 这样的事务范围标识的持久层,对分离的对象(那就是在以前完成了的Session中持久或装载过的实例)进行引用是否是可容忍的?


1楼2012-09-21 15:35回复


    2楼2012-09-21 15:38
    回复
      2026-04-25 07:40:49
      广告
      不感兴趣
      开通SVIP免广告


      4楼2012-09-24 09:55
      回复