第 4 章  Persistence


本章为读者提供了对 Business Process Manager 的"persistence"功能的详细了解。
大多数时间都用来执行跨越多个事务的进程。持久性 功能的主要目的是在等待状态发生时存储 进程执行。将进程执行视为 状态机器 会很有帮助。目的是将进程执行状态机器从一个状态移到单个事务中的下一个状态。
进程定义可以以三种不同的形式表示,即 XML、Java 对象或 IaaS 数据库记录。(运行时数据和日志信息还可以以任一格式表示。)

图 4.1. Transformations 和 Different Forms

注意
要了解更多有关进程定义和进程存档的 XML 表示的信息,请参阅 第 14 章 过程定义语言
注意
要了解更多有关如何将进程存档部署到数据库的信息,请参阅 第 14.1.1 节 “ 部署进程归档 ”

4.1.  Persistence 应用程序编程接口

4.1.1.  与配置框架的关系

持久性应用程序编程接口与配置框架集成(请参阅 第 3 章 配置 。) 这可以通过在 JbpmContext 上公开一些 convenience persistence 方法来实现,允许 jBPM 上下文块 调用持久性 API 操作。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
  // Invoke persistence operations here
} finally {
  jbpmContext.close();
}
Copy to Clipboard Toggle word wrap

4.1.2.  JbpmContext 的方便方法

三个最常见的持久性操作是:
  1. Process. 部署
  2. 新的进程执行开始
  3. 进程执行持续
流程部署 通常直接从 图形进程设计 程序或部署流程 辅助 任务 获得。但是,要直接从 Java 完成此操作,请使用以下代码:
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
  ProcessDefinition processDefinition = ...;
  jbpmContext.deployProcessDefinition(processDefinition);
} finally {
  jbpmContext.close();
}
Copy to Clipboard Toggle word wrap
通过指定将作为实例的进程定义来创建新进程执行。执行此操作的最常见方法是引用进程的名称。然后,Chrouting 将在数据库中找到该进程的最新版本。以下是一些演示代码:
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
	String processName = ...;
	ProcessInstance processInstance = 
		jbpmContext.newProcessInstance(processName);
} finally {
	jbpmContext.close();
}
Copy to Clipboard Toggle word wrap
要继续执行进程,请从数据库获取进程实例、令牌或 taskInstance,并在 POJO (Plain Old Java Object) Ercer 对象上调用一些方法。之后,将对 processInstance 所做的更新保存到数据库中。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
	long processInstanceId = ...;
	ProcessInstance processInstance = 
		jbpmContext.loadProcessInstance(processInstanceId);
		processInstance.signal();
		jbpmContext.save(processInstance);
} finally {
	jbpmContext.close();
}
Copy to Clipboard Toggle word wrap
请注意,如果在 JbpmContext 类中使用 jbpmContext.save 方法,则不需要显式调用 ForUpdate 方法。这是因为在 jbpmContext 类关闭时,保存过程会自动运行。例如,可能希望通知 QPC 已完成 某一任务。这可能导致执行继续,因此必须保存与 taskInstance 相关的 processInstance。执行此操作的最便捷方法是使用 loadTaskInstanceForUpdate 方法:
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
	long taskInstanceId = ...;
	TaskInstance taskInstance = 
		jbpmContext.loadTaskInstanceForUpdate(taskInstanceId);
	taskInstance.end();
	} 
finally {
		jbpmContext.close();
}
Copy to Clipboard Toggle word wrap
重要
阅读以下解释,了解如何管理持久性功能并使用 Hibernate 的功能。
JbpmConfiguration 维护一组 ServiceFactories。它们通过 jbpm.cfg.xml 文件进行配置,并根据需要进行实例化。
DbASPServiceFactory 仅在首次需要实例化时。之后,ServiceFactoryJbpmConfiguration 中维护。
DbASPServiceFactory 管理 Hibernate ServiceFactory,但这只会在请求第一次实例化。
Db\":\"ServiceFactory 参数:
  1. isTransactionEnabled
  2. sessionFactoryJndiName
  3. dataSourceJndiName
  4. isCurrentSessionEnabled

图 4.2. Persistence 等级类

当调用 jbpmConfiguration.createJbpmContext () 类时,只创建 JbpmContext。目前没有发生其他与持久性相关的初始化。JbpmContext 管理 Db\":\"Service 类,该类在首次请求时实例化。Db\":\"Service 类管理 Hibernate 会话,该会话也仅在首次需要时实例化。(换句话说,只有在调用需要持久性的第一个操作时,才会打开 Hibernate 会话。)

4.2.  配置 Persistence 服务

4.2.1. The DbPersistenceServiceFactory

Db\":\"ServiceFactory 类有三个配置属性: isTransactionEnabledsessionFactoryJndiNamedataSourceJndiName。要在 jbpm.cfg.xml 文件中指定任何这些属性,请将 Service Factory 指定为 factory 元素中的 bean。这个示例代码演示了如何进行此操作:
<jbpm-context>
  <service name="persistence">
    <factory>
      <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
        <field name="isTransactionEnabled"><false /></field>
        <field name="sessionFactoryJndiName">
          <string value="java:/myHibSessFactJndiName" />
        </field>
        <field name="dataSourceJndiName">
          <string value="java:/myDataSourceJndiName" />
        </field>
      </bean>
    </factory>
  </service>
...
</jbpm-context>
Copy to Clipboard Toggle word wrap
重要
不要混合配置工厂的短和长表示法。(请参阅 第 3.1 节 “ 自定义事实 ”。) 如果工厂只是类的新实例,请使用 factory 属性来引用其工厂类名称,但如果工厂中的属性需要配置,还必须使用长表示法,而 factory 和 bean 必须合并为嵌套元素。
isTransactionEnabled
默认情况下,当第一次检索会话时,Chtrace 将启动一个 Hibernate 事务,如果 jbpmContext 关闭,则 Hibernate 事务将终止。然后,会根据 jbpmContext.setRollbackOnly 是否被调用,事务提交或回滚。(在 TxService 中维护 isRollbackOnly 属性。) 要禁用事务,并禁止使用 Hibernate 管理它们,将 isTransactionEnabled 属性值设置为 false。(此属性只控制 jbpmContext 的行为 ; DbPersistenceService.beginTransaction() 仍可直接使用应用程序编程接口调用,它会忽略 isTransactionEnabled 设置。) 要了解更多有关事务的信息,请参阅 第 4.2.2 节 “ Hibernate Transactions ”
sessionFactoryJndiName
默认情况下,这是 null,这意味着不会从 JNDI 获取会话工厂。如果设置了并且需要会话工厂来创建 Hibernate 会话,它将从 JNDI 获取。
dataSourceJndiName
默认情况下,这是 null,生成 JDBC 连接被委派给 Hibernate。通过指定数据源,一个使 Business Process Manager 从数据源获取 JDBC 连接,并将其提供给 Hibernate whilst 打开新会话。

4.2.1.1.  Hibernate Session Factory

默认情况下,DbASPServiceFactory 使用 classpath 根中的 hibernate.cfg.xml 文件来创建 Hibernate 会话工厂。请注意,Hibernate 配置文件资源在 jbpm.hibernate.cfg.xml 中映射。通过重新配置 jbpm.cfg.xml 来定制它。
<jbpm-configuration>
    <!-- configuration resource files pointing to default
         configuration files in jbpm-{version}.jar -->
    <string name='resource.hibernate.cfg.xml' 
        value='hibernate.cfg.xml' />
    <!-- <string name='resource.hibernate.properties' 
        value='hibernate.properties' /> -->
</jbpm-configuration>
Copy to Clipboard Toggle word wrap
重要
当指定了 resource.hibernate.properties 时,该资源文件中的属性将覆盖 hibernate.cfg.xml 中的所有属性。使用 hibernate.properties 处理 sVirt 升级,而不是更新 hibernate.cfg.xml 以指向数据库。然后,可以复制 hibernate.cfg.xml 文件,而无需重新应用更改。

4.2.1.2.  配置 C3PO 连接池

请参阅 Hibernate 文档,请访问 http://www.hibernate.org/214.html

4.2.1.3.  配置 ehCache 提供程序

要了解如何使用 JBossCache 配置 192.168.1.0/24,请阅读 http://wiki.jboss.org/wiki/Wiki.jsp?page=JbpmConfiguration
要了解如何配置缓存提供程序,以使用 Hibernate,研究 http://www.hibernate.org/hib_docs/reference/en/html/performance.html#performance-cache
附带的 hibernate.cfg.xml 文件包括以下行:
<property name="hibernate.cache.provider_class">
    org.hibernate.cache.HashtableCacheProvider
</property>
Copy to Clipboard Toggle word wrap
它提供此项,因此用户不必自己考虑配置类路径。
警告
不要在生产环境中使用 HibernateHashtableCacheProvider
要使用 ehcache 而不是 HashtableCacheProvider,只需从 classpath 中删除相关行并替换 ehcache.jar。请注意,可能需要搜索与一个环境兼容的正确 ehcache 库版本。

4.2.2.  Hibernate Transactions

默认情况下,在 jbpmContext 上调用持久操作时,使用 "session per transaction" 模式将事务委派给 Hibernate 。在会话第一次打开时,将开始 Hibernate 事务。在 Hibernate 会话关闭前,事务将立即提交。这将在 jbpmContext.close() 中发生。
使用 jbpmContext.setRollbackOnly() 标记进行回滚的事务。要做到这一点,在会话在 jbpmContext.close() 方法内关闭前,事务将会被立即回滚。
要禁止 Business Process Manager 通过 Hibernate 应用程序编程接口调用任何事务方法,将 isTransactionEnabled 属性设置为 false,如 第 4.2.1 节 “The DbPersistenceServiceFactory” 所述。

4.2.3.  JTA Transactions

当在 JBoss Application Server 中使用 TERM 时,最常见地找到受管事务。以下代码示例演示了将事务绑定到 JTA 的常见方法:
<jbpm-context>
  <service name="persistence">
    <factory>
      <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
        <field name="isTransactionEnabled"><false /></field>
        <field name="isCurrentSessionEnabled"><true /></field>
        <field name="sessionFactoryJndiName">
          <string value="java:/myHibSessFactJndiName" />
        </field>
      </bean>
    </factory>
  </service>
</jbpm-context>
Copy to Clipboard Toggle word wrap
接下来,将 Hibernate 会话工厂配置为使用数据源,并将 Hibernate 本身绑定到 Transaction Manager。如果使用多个数据源,请将其绑定到 XA 数据源
<hibernate-configuration>
    <session-factory>

        <!-- hibernate dialect -->
        <property name="hibernate.dialect">
            org.hibernate.dialect.HSQLDialect
        </property>

        <!-- DataSource properties (begin) -->
        <property name="hibernate.connection.datasource">
            java:/JbpmDS
        </property>

        <!-- JTA transaction properties (begin) -->
        <property name="hibernate.transaction.factory_class">
            org.hibernate.transaction.JTATransactionFactory
        </property>
    
        <property name="hibernate.transaction.manager_lookup_class">
            org.hibernate.transaction.JBossTransactionManagerLookup
        </property>

        <property name="jta.UserTransaction">
            java:comp/UserTransaction
        </property>

    </session-factory>
</hibernate-configuration>
Copy to Clipboard Toggle word wrap
注意
有关将 Hibernate 绑定到交易管理器的更多信息,请参阅 http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#configuration-optional-transactionstrategy
接下来,将 Hibernate 配置为使用 XA 数据源
这些配置允许企业 Bean 使用 CMT Whilst Web 控制台使用 BMT。(这就是为什么还指定了 jta.UserTransaction。)

4.2.4.  自定义查询

Yum 使用的所有 SQL 查询都可在一个中央配置文件中找到。该资源文件在 hibernate.cfg.xml 配置文件中被引用:
<hibernate-configuration>
    <!-- hql queries and type defs -->
    <mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />
</hibernate-configuration>
Copy to Clipboard Toggle word wrap
要自定义一个或多个查询,请备份原始文件。接下来,将自定义版本放在 classpath 上,然后更新 hibernate.cfg. xml 中的 org/jbpm/db/hibernate.queries.hbm.xml 的引用,以指向自定义版本。

4.2.5.  数据库兼容性

lsblk 在 Hibernate 支持的任何数据库上运行。

4.2.5.1.  JDBC 连接的隔离级别

将 JDBC 连接的数据库隔离级别设置为至少 READ_COMMITTED
警告
如果设置为 READ_UNCOMMITTED,(最小级别为零,由 Hypersonic支持的唯一隔离级别),则作业执行器 中可能会出现竞争条件。这些情况可能会在发生多个令牌同步时出现。

4.2.5.2.  更改数据库

要将 Business Process Manger 重新配置为使用不同的数据库,请按照以下步骤执行:
  • 将 JDBC 驱动程序库存档放在 classpath 中。
  • 更新 192.168.1.0/24 使用的 Hibernate 配置。
  • 在新数据库中创建一个模式。

4.2.5.3.  数据库架构

jbpm.db 子项目包含驱动程序、指令和脚本,以帮助用户开始使用自己选择的数据库。如需更多信息,请参阅 readme.html (在 jbpm.db 项目的根目录中找到)。
注意
Inhilst 能够为任何数据库生成 DDL 脚本,这些模式并不总是像它们一样高效。考虑要求您的公司数据库管理员查看生成的 DDL,以便他或她可以选择列类型和索引。
以下 Hibernate 配置选项可以在开发环境中使用:将 hibernate.hbm2ddl.auto 设置为 create-drop,并在应用程序首次使用数据库时自动创建模式。当应用程序关闭时,模式将被丢弃。
4.2.5.3.1. Programmatic 数据库模式操作
jBPM 提供了一个 API,用于通过 org.jbpm.JbpmConfiguration 方法 createSchemadropSchema 创建和丢弃数据库模式。请注意,除配置的数据库用户的权限外,调用这些方法没有约束。
注意
以上 API 组成了类 org.jbpm.db.JbpmSchema 提供的更广泛的功能:

4.2.5.4.  合并 Hibernate 类

合并 Hibernate 和 jBPM 持久类带来了两个主要优势。会话、连接和事务管理变得更加简单,因为通过将它们合并到一个 Hibernate 会话工厂中,它们只会有一个 Hibernate 会话和一个 JDBC 连接。因此,Eyterch 更新将与域模型的更新位于同一个事务中。这消除了对事务管理器的需求。
其次,它允许一个将一个 Hibernate 持久性对象放到进程变量中,而无需额外的工作。
要实现此目的,请创建一个中央 hibernate.cfg.xml 文件。最简单的是使用默认 jBPM hibernate.cfg.xml 作为起点,并添加对一类 Hibernate 映射文件的引用来自定义它。

4.2.5.5.  自定义 sVirt Hibernate 映射文件

按照以下步骤自定义任何 jBPM Hibernate 映射文件:
  1. 复制来自源的 SOAP Hibernate 映射文件(src/jbpm-jpdl-sources.jar)。
  2. 将复制放在 classpath 的位置,(表明它与之前相同的位置。
  3. 更新 hibernate.cfg.xml中自定义映射文件的引用

4.2.5.6.  第二级缓存

在加载一次后,使用 Hibernate 的第二个级别缓存 将进程定义保留在内存中。进程定义类和集合在 Hibernate 映射文件中配置,以便 cache 元素类似如下:
<cache usage="nonstrict-read-write"/>
Copy to Clipboard Toggle word wrap
由于进程定义永远不会更改,因此可以接受将它们保留在第二级缓存中。(请参阅 第 14.1.3 节 “ 更改部署的进程定义 ”。)
默认缓存策略设置为 nonstrict-read-write。在运行时执行过程中,进程定义保留静态,允许实现最大缓存。实际上,设置缓存策略 read-only 甚至适合于运行时执行,但该设置不允许部署新进程定义。
在阅读本章中,您已了解到了与 Dan 中持久性主题相关的理论信息和实际建议,包括如何将 Hibernate 用于其完整潜在。
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat