返回介绍

5.2. 事务

发布于 2023-09-17 23:40:35 字数 5030 浏览 0 评论 0 收藏 0

我们会逐步说明(Flowable)发行版里,Spring示例中的SpringTransactionIntegrationTest。下面是我们示例中使用的Spring配置文件(SpringTransactionIntegrationTest-context.xml)。下面的小节包含了dataSource(数据源),transactionManager(事务管理器),processEngine(流程引擎)以及Flowable引擎服务。

将DataSource传递给SpringProcessEngineConfiguration(使用“dataSource”参数)时,Flowable会在内部使用org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy对得到的数据源进行包装(wrap)。这是为了保证从数据源获取的SQL连接与Spring的事务可以协同工作。这样也就不需要在Spring配置中对数据源进行代理(proxy)。但仍然可以将代理TransactionAwareDataSourceProxy传递给SpringProcessEngineConfiguration——在这种情况下,不会再进行包装。

请确保如果自行在Spring配置中声明了TransactionAwareDataSourceProxy,则不要将它用在已经配置Spring事务的资源上(例如DataSourceTransactionManager与JPATransactionManager。它们需要未经代理的数据源)。

<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

  <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
  <property name="driverClass" value="org.h2.Driver" />
  <property name="url" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
  <property name="username" value="sa" />
  <property name="password" value="" />
  </bean>

  <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource" />
  </bean>

  <bean class="org.flowable.spring.SpringProcessEngineConfiguration">
  <property name="dataSource" ref="dataSource" />
  <property name="transactionManager" ref="transactionManager" />
  <property name="databaseSchemaUpdate" value="true" />
  <property name="asyncExecutorActivate" value="false" />
  </bean>

  <bean class="org.flowable.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>

  <bean factory-bean="processEngine" factory-method="getRepositoryService" />
  <bean factory-bean="processEngine" factory-method="getRuntimeService" />
  <bean factory-bean="processEngine" factory-method="getTaskService" />
  <bean factory-bean="processEngine" factory-method="getHistoryService" />
  <bean factory-bean="processEngine" factory-method="getManagementService" />

...

这个Spring配置文件也包含了在这个示例中要用到的bean与配置:

<beans>
  ...
  <tx:annotation-driven transaction-manager="transactionManager"/>

  <bean class="org.flowable.spring.test.UserBean">
  <property name="runtimeService" ref="runtimeService" />
  </bean>

  <bean class="org.flowable.spring.test.Printer" />

</beans>

可以使用任何Spring支持的方式创建应用上下文(application context)。在这个例子中,可以使用classpath中的XML资源配置来创建Spring应用上下文:

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
	"org/flowable/examples/spring/SpringTransactionIntegrationTest-context.xml");

或者在单元测试中:

@ContextConfiguration(
  "classpath:org/flowable/spring/test/transaction/SpringTransactionIntegrationTest-context.xml")

然后就可以获取服务bean,并调用它们的方法。ProcessEngineFactoryBean会为服务加上额外的拦截器(interceptor),并为Flowable服务方法设置Propagation.REQUIRED事务级别。这样,我们就可以使用repositoryService部署流程:

RepositoryService repositoryService =
  (RepositoryService) applicationContext.getBean("repositoryService");
String deploymentId = repositoryService
  .createDeployment()
  .addClasspathResource("org/flowable/spring/test/hello.bpmn20.xml")
  .deploy()
  .getId();

还有另一种方法也可以使用。如果userBean.hello()方法在Spring事务中,Flowable服务方法调用就会加入这个事务。

UserBean userBean = (UserBean) applicationContext.getBean("userBean");
userBean.hello();

UserBean看起来像下面这样。请记着在上面的Spring bean配置中,我们已经将repositoryService注入了userBean。

public class UserBean {

  /** 已经由Spring注入 */
  private RuntimeService runtimeService;

  @Transactional
  public void hello() {
  // 可以在你的领域模型(domain model)中进行事务操作,
  // 它会与Flowable RuntimeService的startProcessInstanceByKey
  // 合并在同一个事务里
  runtimeService.startProcessInstanceByKey("helloProcess");
  }

  public void setRuntimeService(RuntimeService runtimeService) {
  this.runtimeService = runtimeService;
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文