# 7. 流管理的持久性

## 7.1.导言

大多数应用程序以某种方式访问数据。许多修改由多个用户共享的数据，因此需要事务性数据访问属性。它们通常将关系数据集转换成域对象，以支持应用程序处理。Web 流提供了“流管理的持久性”，其中流可以为你创建、提交和关闭对象持久性上下文。Web 流集成了 Hibernate 和 JPA 对象持久性技术。

除了流管理的持久性之外，还有一种模式是在应用程序的服务层中完全封装持久性 CECONTEXT 管理。在这种情况下，Web 层不涉及持久性，而是完全与传递给服务层并由服务层返回的分离对象一起工作。本章将重点讨论流管理的持久性，探讨如何以及何时使用该特性。

## 7.2.flowscoped 持续 concecontext

此模式在流启动时在`flowScope`中创建`PersistenceContext`，在流执行过程中使用该上下文进行数据访问，并在最后向持久性实体提交所做的更改。这种模式只在流执行结束时向数据库提交更改，从而提供了中间编辑的隔离。这种模式通常与乐观锁定策略结合使用，以保护由多个用户并行修改的数据的 Integrity。为了支持在一段较长的时间内保存和重新启动流的进程，必须使用流状态的持久存储。如果不需要保存和重新启动功能，则基于 HTTP会话的标准流状态存储就足够了。在这种情况下，会话在提交之前到期或终止可能会导致更改丢失。

要使用 FlowScoped PersistentenceContext 模式，首先将你的流标记为`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
                          http://www.springframework.org/schema/webflow/spring-webflow.xsd">

    <persistence-context />

</flow>

```

然后配置正确的`FlowExecutionListener`将此模式应用到你的流。如果使用 Hibernate，则注册`HibernateFlowExecutionListener`。如果使用 JPA，则注册`JpaFlowExecutionListener`。

```
<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。这样的数据访问操作应该总是在非事务或只读事务中执行，以保持中间编辑的隔离。

## 7.3.流管理的持久性和子流

管理的流`PersistenceContext`被自动扩展（传播）到子流，假设该子流还具有`<perstistence-context/>`变量。当子流重新使用其父进程启动的`PersistenceContext`时，当达到结束状态时，它会忽略提交标志，从而将最终决定（提交或不提交）推迟到其父进程。