15. 流程管理的持久化
大多数应用程序以某种方式访问数据。 许多应用程序修改由多个用户共享的数据,因此需要事务性数据访问属性。 它们通常将关系数据集转换为域对象,以支持应用程序处理。 Web Flow 提供了“流程管理的持久性”,其中流程可以为您创建、提交和关闭对象持久性上下文。 Web Flow 集成了 Hibernate 和 JPA 对象持久化技术。
除了流程管理的持久化之外,还有一种模式是将PersistenceContext管理完全封装在应用程序的服务层中。 在这种情况下,Web层不参与持久化。 相反,它完全通过传递给服务层并由服务层返回的分离对象来工作。 本章重点介绍流程管理的持久化,并探讨如何以及何时使用此功能。
15.1. 流程作用域PersistenceContext
此模式在流启动时在 flowScope 中创建一个 PersistenceContext,在流执行过程中使用该上下文进行数据访问,并在最后提交对持久化实体所做的更改。 此模式通过仅在流执行结束时将更改提交到数据库,提供了中间编辑的隔离性。 此模式通常与乐观锁定策略结合使用,以保护多个用户并行修改的数据完整性。 为了支持长时间保存和重新启动流的进度,必须使用持久化存储来保存流状态。 如果不需要保存和重新启动功能,则基于标准 HTTP 会话的流状态存储就足够了。 在这种情况下,如果会话在提交之前过期或结束,可能会导致更改丢失。
要使用 flow-scoped PersistenceContext 模式,首先将您的 flow 标记为 persistence-context,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
https://www.springframework.org/schema/webflow/spring-webflow.xsd">
<persistence-context />
</flow>
然后配置正确的 FlowExecutionListener 以将此模式应用到您的流程。 如果使用 Hibernate,请注册 HibernateFlowExecutionListener。 如果使用 JPA,请注册 JpaFlowExecutionListener。 以下示例使用 JPA:
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="jpaFlowExecutionListener" />
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<bean id="jpaFlowExecutionListener"
class="org.springframework.webflow.persistence.JpaFlowExecutionListener">
<constructor-arg ref="entityManagerFactory" />
<constructor-arg ref="transactionManager" />
</bean>
要触发最后的提交,请使用 commit 属性注解您的 end-state 元素,如下所示:
<end-state id="bookingConfirmed" commit="true" />
就是这样。 当您的流程开始时,监听器会负责在flowScope中分配一个新的EntityManager。 您可以通过特殊的persistenceContext变量随时在流程中引用这个EntityManager。 此外,当您使用Spring管理的数据访问对象进行任何数据访问时,都会自动使用此EntityManager。 此类数据访问操作应始终以非事务性或只读事务方式运行,以保持中间编辑的隔离性。