繁体   English   中英

JSR 352 Spring批处理:事务管理

[英]JSR 352 Spring Batch: Transaction Management

我尝试在Websphere的JSR 352模式下使用Spring Batch。 (Websphere 8.0,Spring Batch 3.0.1)

据我了解的文档,Spring应该处理事务,即在调用步骤的ItemReader之前开始事务,在调用ItemWriter之后提交事务,等等。

但是,在我的情况下,调用ItemReader(userTransaction.getStatus()== 6)时没有事务处于活动状态。 如果我自己在itemReader中启动事务,则我的代码有效,但是我的理解是我不必这样做。

我怀疑问题出在我设置批次的方式上。

这是显示问题的示例代码:

META_INF / batch.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">


<tx:jta-transaction-manager />

</beans>

META-INF / batch-jobs / samplebatch3.xml:

<?xml version="1.0" encoding="UTF-8"?>


<job version="1.0"
     id="samplebatch3" 
     xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">
 <step id="step1">
     <chunk  checkpoint-policy="item"
            item-count="5">
            <reader ref="my.jbatchtest.samplebatch3.SampleReader" />
            <processor ref="my.jbatchtest.samplebatch3.SampleProcessor"/>
            <writer ref="my.jbatchtest.samplebatch3.SampleWriter" />
     </chunk> 
  </step>
</job>

ItemReader:

package my.jbatchtest.samplebatch3;

import java.io.Serializable;

import javax.batch.api.chunk.ItemReader;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;

import org.xadisk.connector.outbound.XADiskConnectionFactory;

public class SampleReader implements ItemReader {

    private UserTransaction utx;


    public SampleReader() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public void open(Serializable checkpoint) throws Exception {

        utx = (UserTransaction) new InitialContext().lookup("jta/usertransaction");   
        System.out.println("Status before begin:"+utx.getStatus());
        utx.begin();
        System.out.println("Status after begin:"+utx.getStatus());

    }

    @Override
    public void close() throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public Object readItem() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Serializable checkpointInfo() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

}

ItemReader的调试输出:

[07.10.14 12:52:48:881 CEST] 00000039 SystemOut     O Status before begin:6
[07.10.14 12:52:48:881 CEST] 00000039 SystemOut     O Status after begin:0

我的问题是:

  1. 我的理解正确吗,春季批次应该管理交易?
  2. 那为什么不这样做呢?

让我来谈谈这里提出的一些问题。 完全公开,我目前是Spring Batch的项目负责人,同时还是JSR-352的专家组成员。

Spring Batch和JSR-352的状态如何
从3.0.0版本开始的Spring Batch符合JSE-352的所有SE要求。 JSR-352的需求分为SE和EE分组。 我们没有解决规范中指定的与Spring Batch的“常规”处理不同的任何EE功能。

为什么Spring Batch没有实现EE特定功能?
我们出于一个简单的原因走了只执行SE要求的路线。 这些是我们可以通过可用的TCK验证符合规范的唯一要求。 验证EE特定要求的唯一方法是将TCK作为应用服务器(Oracle CTS)认证的一部分运行,Spring Batch显然不是其一部分,也无法访问(假设必须获得许可) 。

我们已经请求了一个可用于验证EE功能的TCK版本,到目前为止,我们收到的回复是: “在GitHub上开放TCK供公众捐款时,这无疑是一个增强,我们很乐意接受帮助。”

像任何优秀的开发人员一样,我们也不想在没有测试的情况下开发新功能。 我们希望能够验证我们已实现的要求。 在这种情况下,验证步骤在于针对我们的代码执行TCK,这是我们目前无法执行的操作。 无法执行TCK,使我们处于以“认为”正确的方式实施EE功能的风险,将其释放,然后如果/当可以运行TCK时不得不改变其行为,这是直接矛盾的。 JCP试图提供的可移植性。

那BATCH-2240呢?
当前的BATCH-2240 并不是要求修复Spring Batch JSR-352实现的行为。 相反,它要求在事务中包装ItemStream#open()ItemStream#close()方法的行为仅影响正常的Spring Batch处理。 修复BATCH-2240无法直接解决Spring Batch的JSR-352的行为。 它被标记为次要改进,因为它在我们的JSR-352实现中并未被视为错误,而在我们的常规Spring Batch处理中被视为一项附加功能。

回答原始问题
1. 我的理解正确吗,春季批次应该管理交易? -是的,您的理解是正确的。 Spring Batch确实处理事务。 通过基于块的步骤,可以在事务外部调用open和close方法,从而可以重置实现组件的状态。 在Spring Batch中,没有什么可以阻止您使用TransactionTemplate获得类似功能的代码包装在TransactionTemplate中。
2. 那为什么不这样做呢? -我希望以上几点能解决这个问题。

结论
一旦我们有一种方法可以验证我们已经解决了它们的问题,从而保证JCP试图实现的可移植性,那么我们想解决JSR-352的EE特定功能。 我们认为,正确的方法是拥有可以运行的标准化TCK。 一旦解决了这一问题,解决规范的EE版本与Spring Batch之间的差异将成为当务之急。

阅读并逐步完成Spring Batch代码并阅读JSR 352规范后,我认为这可能是Spring Batch中的错误。

我不喜欢将问题归咎于像Spring这样经过良好测试的库,因此我仍然可能是错的。 这是我发现的:

Spring调用读写器的open()方法,然后执行读取,处理和写入的主要批处理周期。 完成循环后,在读取器和写入器上调用close()。

问题在于,spring批处理仅在事务上下文内运行主批处理周期。 它不会为open()和close()调用启动事务。

根据规范,这些调用应在自己的事务中运行。 这是从JSR 352规范中得出的:

11.6 Regular Chunk Processing

1. <Create StepContext>
2. <Store step level properties in StepContext>
3. <->[StepListener.beforeStep...] // thread A
4. [<begin transaction> ]
5. <->ItemReader.open // thread A
6. <->ItemWriter.open // thread A
7. [<commit transaction> ]
8. // chunk processing:
9. <repeat until no more items> {
   a. <begin checkpoint [<begin transaction> ]>
   b. <repeat until commit criteria reached> {
        i. <->ItemReader.readItem // thread A
       ii. <->ItemProcessor.processItem // thread A
      iii. <add item to buffer>
   c. }
   d. <->ItemWriter.writeItems // thread A
   e. <->[ItemReader.checkpointInfo] // thread A
   f. <->[ItemWriter.checkpointInfo] // thread A
   g. <Store StepContext persistent area>
   h.
   i. <commit checkpoint (commit transaction)>
10. }
11. [<begin transaction> ]
12. <->ItemWriter.close // thread A
13. <->ItemReader.close // thread A
14. [<commit transaction> ]
15. <->[StepListener.afterStep...] // thread A
16. <Store StepContext persistent area>
17. <Destroy StepContext>

第4、7、11和14行永远不会在春季批处理中发生。

我在我的代码中看到了这种行为(open()和close()中没有打开的事务),并且也反映在春季批处理代码中:主循环有明显的事务括号,open()和close()没有事务代码)

我发现没有办法在spring.io网站上发布错误,仅找到stackoverflow.com的链接。 也许来自春季团队的人会看到并给出一些反馈(或至少将其传递给开发人员)

Upate :这似乎是一个已知问题: https : //jira.spring.io/browse/BATCH-2240规范的注释似乎表明,在此处开始事务是可选的,这使编写读写程序变得很麻烦,因为我必须检查我是否有一个有效的交易,并需要创建自己的交易支架。

在samplebatch3.xml上,您需要在step和chunk标记之间声明一个tasklet,在tasklet标记上,您要引用Spring Batch将使用的事务管理器,否则他将不知道要使用哪个事务管理器。 请参阅此页面上的5.1.1节:

http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html

编辑:抱歉,我忘记了使用jsr-352而不是普通的Spring批处理,请参见下面的链接,它指定了一些需要传递给框架的设置,其中之一是事务管理器

http://docs.spring.io/spring-batch/trunk/reference/html/jsr-352.html

在本文上,有一个配置示例:

https://blog.codecentric.de/zh/2014/08/writing-jsr-352-style-jobs-spring-batch-part-1-configuration-options/

请参阅“如何自定义标准配置”部分

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM