Java JSR352Spring批处理:事务管理
我尝试在Websphere中以JSR352模式使用Spring批处理。(Websphere 8.0,Spring批处理3.0.1) 据我对文档的理解,spring应该处理事务,即在调用步骤的ItemReader之前开始事务,在调用ItemWriter之后提交事务,等等 但是,在我的例子中,调用ItemReader时没有事务处于活动状态(userTransaction.getStatus()==6)。如果我自己在itemReader中启动事务,我的代码就可以工作,但我的理解是我不应该这样做 我怀疑问题在于我设置批次的方式 这是显示问题的示例代码: META_INF/batch.xml:Java JSR352Spring批处理:事务管理,java,spring-batch,websphere-8,Java,Spring Batch,Websphere 8,我尝试在Websphere中以JSR352模式使用Spring批处理。(Websphere 8.0,Spring批处理3.0.1) 据我对文档的理解,spring应该处理事务,即在调用步骤的ItemReader之前开始事务,在调用ItemWriter之后提交事务,等等 但是,在我的例子中,调用ItemReader时没有事务处于活动状态(userTransaction.getStatus()==6)。如果我自己在itemReader中启动事务,我的代码就可以工作,但我的理解是我不应该这样做 我怀疑
<?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>
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;
}
}
[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
我的问题是:
在阅读并逐步阅读spring批处理代码以及JSR352规范之后,我认为这可能是spring批处理中的一个bug 我不喜欢把问题归咎于像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>
11.6常规块处理
1.
2.
3.[StepListener.beforeStep…]//线程A
4.[ ]
5.ItemReader.open//线程A
6.ItemWriter.open//线程A
7.[ ]
8. // 区块处理:
9{
A.
b{
i、 ItemReader.readItem//线程A
ii.ItemProcessor.processItem//线程A
三,。
规范的符号似乎表明,在这里启动事务是可选的,这使得编写读写器变得很麻烦,因为我必须检查是否有有效的事务,并创建自己的事务括号是必要的。在阅读并逐步阅读spring批处理代码,以及阅读JSR352规范之后,我将这可能是spring批处理中的一个错误
我不喜欢把问题归咎于像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>
11.6常规块处理
1.
2.
3.[StepListener.beforeStep…]//线程A
4. [ ]
5.ItemReader.open//线程A
6.ItemWriter.open//线程A
7. [ ]
8//块处理:
9. {
A.
b{
i、 ItemReader.readItem//线程A
ii.ItemProcessor.processItem//线程A
三,。
规范的符号似乎表明,在这里启动事务是可选的,这使得编写读写器很麻烦,因为我必须检查是否有有效的事务,并创建自己的事务括号是必要的。在samplebatch3.xml上,您需要在步骤和块标记之间声明一个tasklet,并且在tasklet标记上,您将引用放在Spring批处理将使用的事务管理器上,否则他将不知道使用哪个事务管理器。请参阅本页第5.1.1节:
编辑:抱歉,我忘了您使用jsr-352而不是纯Spring批处理,请参见下面的链接,它指定了一些需要传递给框架的设置,其中之一是事务管理器
在本文中,有一个配置示例:
请参见samplebatch3.xml上的“如何自定义标准配置”一节,您需要在步骤标记和区块标记之间声明一个tasklet,并且在tasklet标记上,您可以引用Spring批将使用的事务管理器,否则他将不知道使用哪个事务管理器。请参见本页的第5.1.1节:
编辑:抱歉,我忘了您使用jsr-352而不是纯Spring批处理,请参见下面的链接,它指定了一些需要传递给框架的设置,其中之一是事务管理器
在本文中,有一个配置示例:
请参阅“如何定制标准配置”一节,让我插话一下这里提出的几个问题。完全公开,我目前是Spring Batch的项目负责人,也是JSR-352的专家组成员
Spring Batch和JSR-352的状态如何
从3.0.0版开始,Spring Batch符合JSR-352的所有SE要求。JSR-352的要求分为SE和EE两类。我们没有解决规范中规定的与Spring Batch“正常”处理不同的任何EE特性
为什么Spring Batch没有实现特定于EE的功能?
我们之所以只实施SE需求,原因很简单。我们可以通过可用的TCK验证这些需求是否符合规范。验证EE特定需求的唯一方法是将TCK作为应用服务器(Oracle的CTS)认证的一部分运行,Spring Batch显然不是其中的一部分,也无权访问(考虑到它必须获得许可)
我们已经请求了一个TCK版本,我们可以根据今天的响应验证EE功能