`
whitesock
  • 浏览: 483781 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

OpenJPA (6)

    博客分类:
  • EE
阅读更多

8 Object Locking
8.1 Configuring Default Locking
    如何使用lock对load时的性能有重要的影响。OpenJPA通过openjpa.ReadLockLevel和openjpa.WriteLockLevel来配置缺省的事务读写lock level。这些缺省配置只适用于非乐观事务;在乐观事务中,OpenJPA缺省不进行lock。在尝试获取lock时,可以通过openjpa.LockTimeout配置最长的等待时间(缺省值-1指定没有限制),超过这个时间后OpenJPA会抛出异常。配置方式如下:

<property name="openjpa.ReadLockLevel" value="none"/>
<property name="openjpa.WriteLockLevel" value="write"/>
<property name="openjpa.LockTimeout" value="30000"/>

 

8.2 Configuring Lock Levels at Runtime
    在每个事务开始时,OpenJPA初始化EntityManager的缺省lock levels和time out。在运行时可以通过EntityManager的FetchPlan 接口修改这些配置。也可以通过Query相关的fetch plan修改Query级别上的配置。这些运行时的修改可以在乐观事务中使用,但是不能在事务之外进行锁定。以下是个简单的例子:

// load stock we know we're going to update at write lock mode
em.getTransaction().begin();
Query q = em.createQuery("select s from Stock s where symbol = :s");
q.setParameter("s", symbol);

OpenJPAQuery oq = OpenJPAPersistence.cast(q);
FetchPlan fetch = oq.getFetchPlan ();
fetch.setReadLockMode(LockModeType.WRITE);
fetch.setLockTimeout(3000); // 3 seconds
Stock stock = (Stock) q.getSingleResult();

// load an object we don't need locked at none lock mode
fetch = OpenJPAPersistence.cast(em).getFetchPlan();
fetch.setReadLockMode(null);
Market market = em.find(Market.class, marketId);

stock.setPrice(market.calculatePrice(stock));
em.getTransaction().commit();

 

8.3 Lock Manager
    OpenJPA 内部使用org.apache.openjpa.kernel.LockManager 处理locking相关的实际工作。可以通过openjpa.LockManager 属性进行配置,它有以下选项。

 

8.3.1 pessimistic
    这个选项是org.apache.openjpa.jdbc.kernel.PessimisticLockManager 的一个别名。它使用SELECT FOR UPDATE (或其它等效的)语句锁定跟entity实例对应的数据库行,并且不区分read locks和write locks,也就是说所有的locks都是write locks。例如:

<property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=true)"/>

 

8.3.2 none
    这个选项是org.apache.openjpa.kernel.NoneLockManager的一个别名。它不进行任何锁定。例如:

<property name="openjpa.LockManager" value="none"/>

 

8.3.3 version
    这个选项是org.apache.openjpa.kernel.VersionLockManager的一个别名。它不进行排他锁定;相反,在事务结束时,它通过校验version来确保被read locks锁定的对象的一致性。无论被write locks锁定的对象是否被修改,其version都会被累加。为了避免脏读,事务的隔离级别应该至少为"read committed"以上。

 

8.4 Rules for Locking Behavior
    OpenJPA的隐含锁定行为有以下规则:

  1. 在事务中,当第一次读取某个对象的persistent state的时候,OpenJPA使用fetch plan中当前的read lock level锁定这个对象。未来对这个对象上的lazy persistent state的读取也采用相同的read lock level(无论fetch plan中的lock level是否改变)。
  2. 在事务中,当第一次修改某个对象的persistent state的时候,OpenJPA使用该对象第一次被读取时的write lock level(无论fetch plan中的lock level是否改变)。如果对象在之前没有被读取过,那么使用当前的write lock level。
  3. 当使用persistent relation field 访问某个对象的时候,这个对象在load过程中被当前fetch plan中的lock level锁定,而不是持有这个field的对象所"记住"的那个lock level。
  4. 在事务中,每次访问某个对象的时候,这个对象会被当前的read lock level重新锁定,并且这个read lock level会被该对象"记住"(规则1,2)。
  5. 如果显式地通过locking APIs锁定某个对象,那么这些操作都是再次锁定,并且这个lock level会被该对象"记住"(规则1,2)。
  6. 如果某个对象已经被锁定,那么尝试使用低级别的lock level再次锁定该对象会被忽略,也就是说在事务中,lock level不能被降低。 

8.5 Known Issues and Limitations
    出于性能的考虑和数据库的限制等,locking有以下限制:

  • 在乐观事务中,OpenJPA通常会直到flush或commit前才真正开始事务。当使用pessimistic lock manager时,OpenJPA必须在乐观事务中锁定某个对象时开始事务。这因为pessimistic lock manager需要使用数据库的lock。此时OpenJPA会以INFO级别在openjpa.Runtime category中输出一条日志。
  • 出于性能的考虑,OpenJPA只保证在从datastore中得到了某个对象的persistent state之后才进行锁定。这意味这其它事务可能在锁定前修改其persistent state。可以通过在锁定后refresh这个对象来确保这个对象被成功锁定。当使用pessimistic lock manager的时候,这个情况只在无法使用SELECT FOR UPDATE(或其它等效的)语句的时候,例如某些数据库不支持SELECT FOR UPDATE中使用join。此时OpenJPA会以INFO级别在openjpa.Runtime category中输出一条日志。

 

9 Enhancement
    OpenJPA使用enhancer来支持运行时性能优化、延迟加载、脏检查等功能。被enhancer修改过的字节码是Java debugger兼容的,而且很好地保留了stack trace中的行号。唯一的需要注意的是,如果采用property access,那么修改后的getter和setter方法名,在stack track中或者step-through时,会加上"pc"前缀。

 

9.1 Enhancing at Build Time
    Enhancer可以在build的时候被调用。如果对已经加强过的class再次进行加强,那么不会对class文件做更多的修改。可以在命令行上通过PCEnhancer类进行加强,例如:

java org.apache.openjpa.enhance.PCEnhancer Magazine.java

    以下是几个可选的命令行参数: 

  • -directory/-d <output directory>: 输出的class文件的路径。
  • -enforcePropertyRestrictions/-epr <true/t | false/f>: 如果entity使用property access,但是却没有遵守相关限制的时候,是否抛出异常。缺省是false。
  • -addDefaultConstructor/-adc <true/t | false/f>: JPA规范要求所有的persistence class必须提供一个无参构造函数。这个标志指示enhancer在persistence class没有提供无参构造函数的时候,是否创建一个protected型的无参构造函数。缺省是true。
  • -tmpClassLoader/-tcl <true/t | false/f>: 是否使用临时classloader加载persistence class。 缺省是true。

9.2 Enhancing on Deployment
    在entities被部署到container的时候,Java EE 5 规范包含hooks来自动加强这些entities。 因此,如果使用Java EE 5兼容的应用服务器,OpenJPA会自动在运行时加强entities。如果某些entites使用了build时的enhancement,那么OpenJPA运行时enhancer会识别并略过这些已经加强过的entities。

9.3 Enhancing at Runtime
    在类被载入到JVM的时候,可以使用OpenJPA agent来加强被载入的persistence class。OpenJPA agent是在应用的main方法执行之前被调用的classes。OpenJPA agent使用JVM hooks来拦截并加强被载入的包含persistence metadata的类。在每一个被载入的类中查找persistence metadata可能会减慢应用的初始化速度。可以设置persistent class list来指示agent只查找包含在persistent class list中的类。以下是使用OpenJPA agent的几个例子:

java -javaagent:/home/dev/openjpa/lib/openjpa.jar com.xyz.Main
java -javaagent:/home/openjpa/lib/openjpa.jar=addDefaultConstructor=false com.xyz.Main

    可以使用OpenJPA's plugin syntax来为agent传递配置。此外也支持以下的选项: 

  • addDefaultConstructor: 输出的class文件的路径。
  • enforcePropertyRestrictions: 如果entity使用property access,但是却没有遵守相关限制的时候,是否抛出异常。缺省是false。
  • scanDevPath: 是否检查classpath来查找persistence class。如果没有指定persistent class list,同时设置这个标志为true,那么OpenJPA会检查每一个被载入到JVM的类。
  • classLoadEnhancement: 指定是否使用load-time class enhancement。缺省是true。
  • runtimeRedefinition: 指定是否使用class redefinition。缺省是true。

9.4 Omitting the OpenJPA enhancer
    OpenJPA并不要求必须运行enhancer。如果没有运行enhancer,OpenJPA使用以下几种可能的替代方法。

9.4.1 Java 6 class retransformation
    如果使用Java 6,那么OpenJPA会自动检测并尝试动态注册ClassTransformer来重定义persistence class。同时OpenJPA也会为persistence class创建子类。当执行query或者遍历关系的时候,OpenJPA会返回子类的对象,因此instanceof操作符仍然会正确工作,但是o.getClass() 会返回子类类型。

9.4.2 Java 5 class redefinition
    如果使用Java 5,并指定了OpenJPA agent,那么OpenJPA会使用Java 5 class redefinition 来重定义没有被agent加强的persistence class。由于agent缺省会进行加强,因此这只有在为agent设置classLoadEnhancement 为false的时候有效(或者其它特殊情况)。

9.4.3 State comparison and subclassing
    在以上情况外,OpenJPA会创建persistence class的子类。然而在有些情况下,OpenJPA无法在访问psersistence state的时候得到通知。
    如果使用property access,那么OpenJPA会为从数据库中查询得到的对象自动创建子类,并返回这个子类作为代理。这个子类中的getter和setter方法中增添了额外的代码以便通知OpenJPA所有对persistence state的访问。对于你自己创建的对象,由于无法使用子类代理,因此会在脏检查的时候使用state比较的方式。在这种方式下要额外保存该对象的一个snap shot以便用于比较。
    如果使用field access,那么OpenJPA无法跟踪对psrsistence state的访问。因此OpenJPA会在脏检查的时候使用state比较的方式,代价是性能上的降低和内存使用的增加。此外,single-valued fields (one-to-one, many-to-one, and any other non-collection or non-map field that has a lazy loading configuration)上的延迟加载的相关配置也被忽略,因为OpenJPA无法跟踪最这些field的访问。

17
8
分享到:
评论
2 楼 chenhailong 2011-06-29  
我也遇到同样的问题
94  example  INFO   [main] openjpa.Runtime - Starting OpenJPA 2.1.0
219  example  INFO   [main] openjpa.jdbc.JDBC - Using dictionary class "org.apache.openjpa.jdbc.sql.MySQLDictionary".
Exception in thread "main" <openjpa-2.1.0-r422266:1071316 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "
com.jpa.chenhailong.Message".
at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:116)
at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:315)
at org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:239)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:213)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:154)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:60)
at com.jpa.chenhailong.Main.main(Main.java:14)
1 楼 lchshu001 2009-11-29  
Exception in thread "main" <openjpa-2.0.0-M3-r422266:822833 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "[class com.beans.Animal]".
at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:117)
at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:305)
at
....................
     
今天刚碰到的一个错误。。。。。
在1.0正常运行,在2.0下就出现了上面的错误

相关推荐

    openjpa 写的一个例子

    OpenJPA,全称Open Java Persistence API,是Java平台上的一个开源对象关系映射(ORM)框架,它实现了Java Persistence API(JPA),用于管理Java应用程序中的持久化数据。在这个"openjpademo"示例中,我们将会探讨...

    openjpa范例及实例工程

    默认情况下,当应用程序第一次获取实体标识时,OpenJPA 框架从数据库中一次性获取 50 个连续的实体标识缓存起来,当下一次应用程序需要获取实体标识时,OpenJPA 将首先检测缓存中是否存在实体标识,如果存在,Open...

    OpenJPA 2.2.1 API (CHM格式)

    OpenJPA  OpenJPA 是 Apache 组织提供的开源项目,它实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大、使用简单的持久化数据管理框架。OpenJPA 封装了和关系型数据库交互的操作,让开发者把注意力集中在编写...

    openjpa 源码 下载 帮助开发人员调试

    OpenJPA,全称Open Java Persistence API,是Apache软件基金会的一个开源项目,它实现了Java持久化API(Java Persistence API,JPA),为Java开发者提供了一种标准的方式来管理和持久化应用程序中的对象。...

    Spring和openJPA集成

    **Spring和OpenJPA集成详解** 在Java世界中,Spring框架和OpenJPA(Open Java Persistence)是两个非常重要的组件。Spring作为一个全面的轻量级应用框架,提供了大量的功能,包括依赖注入、AOP(面向切面编程)、...

    Open JPA2 employee 简单例子

    OpenJPA2是一个开源的对象关系映射(ORM)框架,它是Java Persistence API(JPA)规范的实现。在这个“Open JPA2 employee简单例子”中,我们将深入理解如何使用OpenJPA2来处理数据库中的员工数据。这个示例将帮助...

    Spring中使用OpenJPA

    6. **测试**:编写测试用例,验证Spring和OpenJPA的集成是否成功。 通过以上步骤,你就成功地在Spring项目中集成了OpenJPA,并能够进行基本的数据操作。在实际开发中,你可能还需要配置JPA的其他特性,如缓存、查询...

    openJpa的应用,感觉还可以

    OpenJPA(Open Java Persistence API)是Apache软件基金会下的一个开源项目,它是Java持久层标准JPA(Java Persistence API)的一个实现。JPA是Java EE平台中的一个重要组件,用于管理和处理应用程序中的对象-关系...

    jsf、openJpa学习

    **JSF与OpenJPA整合** 涉及到在JSF应用中使用OpenJPA进行数据访问。这通常包括配置OpenJPA的数据源、实体管理器工厂,以及在JSF Managed Beans中注入实体管理器,以便在处理用户请求时执行CRUD操作。JSF的事件驱动...

    openjpa jar

    6. **性能优化**:OpenJPA提供了多种性能优化选项,如延迟加载(Lazy Loading)、批处理(Batching)和结果集映射(Result Set Mapping)。通过这些设置,开发者可以平衡性能和内存消耗。 7. **插件扩展性**:...

    openJPA官方手册

    ### OpenJPA官方手册知识点概览 #### 一、引言 - **OpenJPA**:作为Apache项目的一部分,OpenJPA是一个开源的Java持久化框架(Java Persistence Framework),它支持Java Persistence API (JPA) 的规范。OpenJPA...

    通过 WebSphere Application Server V6.1 利用 OpenJPA

    安装OpenJPA的步骤通常包括下载OpenJPA的jar文件,将其添加到服务器的类路径中,并在服务器配置中指定OpenJPA作为默认的持久化提供者。 接下来,我们需要创建一个JPA项目。这涉及定义实体类,这些类代表数据库中的...

    Spring MVC+OpenJPA框架

    Spring MVC和OpenJPA是Java开发中常用的两个框架,它们分别在Web应用和持久层处理上发挥着重要作用。Spring MVC是Spring框架的一部分,用于构建高效、灵活的Web应用程序,而OpenJPA则是一个实现了Java Persistence ...

    OpenJPA API 文档 chm格式

    OpenJPA API 文档 chm格式

    Apache OpenJPA 2.1 User's Guide

    ### Apache OpenJPA 2.1 用户指南:Java Persistence API 的深入解析 #### 一、简介 Apache OpenJPA 2.1 是基于 Sun Microsystems 的 Java Persistence 2.0 API (JSR-317 JPA 2.0) 规范实现的一种透明持久化 Java ...

    openjpa:Apache OpenJPA

    Apache OpenJPA-自述文件 前言 感谢您下载此版本的Apache OpenJPA。 Apache OpenJPA是Java Persistence API规范的实现。 执照 此存储库的内容已根据Apache License 2.0 许可 更多信息 可以在openjpa-project子目录...

    openjpa-manual

    ### OpenJPA-Manual 关键知识点解析 #### 一、OpenJPA介绍 **1.1 关于本文档** 本文档旨在提供一个全面且深入的指南,帮助开发人员理解和掌握Java Persistence API(JPA)的核心概念及其在Apache OpenJPA中的实现...

    Openjpa2.2+Mysql+Maven+Servlet+JSP source code

    Openjpa2.2+Mysql+Maven+Servlet+JSP 博客源码: http://blog.csdn.net/shenhonglei1234/article/details/10394379

    apache-openjpa-2.2.1-binary

    6. **性能优化**:OpenJPA提供了一系列的性能调优选项,如批处理操作、延迟加载、结果集缓存等,帮助开发者优化应用程序的性能。 7. **插件式架构**:OpenJPA的架构允许用户自定义策略和实现,以便适应不同的持久化...

Global site tag (gtag.js) - Google Analytics