Spring Batch的事务-Part 1:基础
原文 https://blog.codecentric.de/en/2012/03/transactions-in-spring-batch-part-1-the-basics/
This is the first post in a series about transactions in Spring Batch, you find the second one here, it’s about restarting a batch, cursor based reading and listeners, and the third one here, it’s about skip and retry.
Transactions are important in almost any application, but handling transactions in batch applications is something a little more tricky. In standard online applications you usually have one transaction for one user action, and as a developer you normally just have to assure that your code picks up an existing transaction or creates a new one when there’s none (propagation typeREQUIRED). That’s it. Developers of batch applications have much more headaches with transactions. Of course you cannot have just one transaction for the whole batch, the database couldn’t cope with that, so there have to be commits somewhere in between. A failed batch then doesn’t mean you get the unchanged data back, and when you throw in features like restarting a failed batch, retrying or skipping failing items, you automatically get a complicated transaction behaviour. Spring Batch offers the functionality just mentioned, but how does it do that?
Spring Batch is a great framework, and there is a lot of documentation and some good books, but after reading a lot about Spring Batch I still wasn’t sure about everything regarding transactions, so in the end all that helped to understand everything was looking into the code and a lot of debugging. So, this is no introduction to Spring Batch, I’m gonna focus just on transactions, and I assume that you’re familiar with transactions in Spring (transaction managers, transaction attributes). And since I have to restrict myself a little bit, I will just talk about one-threaded chunk oriented processing.
Chunk oriented steps
Let’s start with a picture that will follow us throughout this and the following blog posts, only changed in little details every now and then to focus on a certain subject.
It’s already telling a lot about Spring Batch and its transactional behaviour. In chunk-oriented processing we have ItemReaders reading items, one after the other, always delivering the next one item. When there are no more items, the reader delivers null. Then we have optional ItemProcessors taking one item and delivering one item, that may be of another type. Finally we haveItemWriters taking a list of items and writing them somewhere.
The batch is separated in chunks, and each chunk is running in its own transaction. The chunk size actually is determined by aCompletionPolicy, as you can see in the illustration at (1): when the CompletionPolicy is fulfilled, Spring Batch stops reading items and starts with the processing. By default, if you use the commit-interval attribute on chunk, you get aSimpleCompletionPolicy that is completed when the number of items you specified in the attribute is read. If you want something more sophisticated you can specify your own CompletionPolicy in the attribute chunk-completion-policy.
This is all quite straight forward, if there’s a RuntimeException being thrown in one of the participating components, the transaction for the chunk is rolled back and the batch fails. Every already committed chunk of course stays in the processed state.
Business data and batch job data
As you might know already, Spring Batch brings a set of database table definitions. These tables are used to store data about the jobs and steps and the different job and step execution contexts. This persistence layer is useful for some kind of history on the one hand, and for restarting jobs on the other hand. If you’re thinking of putting these tables in a different database than your business data: don’t. The data stored there is about the state of the job and the steps, with numbers of processed items, start time, end time, a state identifier (COMPLETED, FAILED and so on) and much more. In addition there is a map for each step (the step execution context) and job (the job execution context) which can be filled by any batch programmer. Changes in this data have to be in line with the transaction running on our business data, so if we have two databases we’ll need for sure aJtaTransactionManager handling different DataSources, suffering in performance as well. So, if you have a choice, put those tables near to your business data. In the following diagram you can see where in the processing step and job data is persisted. As you can see, it doesn’t happen only inside the chunk transaction, for good reasons: we want to have step and job data persisted in the case of a failure, too.
Note that I use little numbers for indicating items that are explained in a text box. The numbers stay in following versions of the diagram while the text box may disappear due to readability. It’s always possible to look up the explanation in a previous version of the diagram.
A failed batch
Until now, the diagram just includes successful processing. Let’s take a look at the diagram including a possible failure.
If you didn’t configure skip or retry functionality (we’ll get to that in the next blog posts) and there’s an uncaughtRuntimeException somewhere in an element executed inside the chunk, the transaction is rolled back, the step is marked asFAILED and the whole job will fail. Persisting step data in a separate transaction at (5) makes sure that the failure state gets into the database.
When I say that an uncaught RuntimeException causes the rollback, then it’s not quite true for every case. We have the option to set no-rollback-exceptions:
<batch:tasklet>
<batch:chunk ... />
<batch:no-rollback-exception-classes>
<batch:include class="de.codecentric.MyRuntimeException"/>
</batch:no-rollback-exception-classes>
</batch:tasklet>
Transaction attributes
One more thing for today: if you don’t configure transaction attributes explicitly, you get the defaults. Transaction attributes are propagation type, isolation level and timeout, for example. You may specify those attributes as shown here:
<batch:tasklet>
<batch:transaction-attributes isolation="READ_COMMITTED" propagation="REQUIRES_NEW" timeout="200"/>
<batch:chunk reader="myItemReader" writer="myItemReader" commit-interval="20"/>
</batch:tasklet>
If you don’t specify them, you’ll get the propagation type REQUIRED and the isolation level DEFAULT, which means that the default of the actual database is used. Normally you don’t want to change the propagation type, but it makes sense to think about the isolation level and check the batch job: am I fine with non-repeatable reads? Am I fine with phantom reads? And: what other applications are accessing and changing the database, do they corrupt the data I’m working on in a way that causes trouble? Is there a possibility to get locks? For more information on the different isolation levels check this wikipedia article.
Conclusion
In this first article on transactions in Spring Batch I explained the basic reader-processor-writer cycle in chunk oriented steps and where the transactions come into play. We saw what happens when a step fails, how to set transaction attributes and no-rollback-exception-classes and how job and step metadata is updated.
Next on the list will be restart, retry and skip functionality: what are the preconditions? How does the transaction management work with these features? Click here for the next blog post in this series about restart, cursor based reading and listeners, andhere for the third post about skip and retry.
Spring Batch的事务-Part 1:基础的更多相关文章
- Spring Batch的事务– Part 3: 略过和重试
原文:https://blog.codecentric.de/en/2012/03/transactions-in-spring-batch-part-3-skip-and-retry/ This i ...
- Spring Batch 中文参考文档 V3.0.6 - 1 Spring Batch介绍
1 Spring Batch介绍 企业领域中许多应用系统需要采用批处理的方式在特定环境中运行业务操作任务.这种业务作业包括自动化,大量信息的复杂操作,他们不需要人工干预,并能高效运行.这些典型作业包括 ...
- spring batch(一):基础部分
spring batch(一):基础部分 博客分类: Spring java spring batch 官网: http://www.springsource.org/spring-batch 下 ...
- 【spring基础】spring声明式事务详解
一.spring声明式事务 1.1 spring的事务管理器 spring没有直接管理事务,而是将管理事务的责任委托给JTA或相应的持久性机制所提供的某个特定平台的事务实现.spring容器负责事物的 ...
- Web基础之Spring AOP与事务
Spring之AOP AOP 全程Aspect Oriented Programming,直译就是面向切面编程.和POP.OOP相似,它也是一种编程思想.OOP强调的是封装.继承.多态,也就是功能的模 ...
- 初探Spring Batch
此系列博客皆为学习Spring Batch时的一些笔记: 为什么我们需要批处理? 我们不会总是想要立即得到需要的信息,批处理允许我们在请求处理之前就一个既定的流程开始搜集信息:比如说一个银行对账单,我 ...
- Spring Batch 专题
如今微服务架构讨论的如火如荼.但在企业架构里除了大量的OLTP交易外,还存在海量的批处理交易.在诸如银行的金融机构中,每天有3-4万笔的批处理作业需要处理.针对OLTP,业界有大量的开源框架.优秀的架 ...
- 陪你解读Spring Batch(一)Spring Batch介绍
前言 整个章节由浅入深了解Spring Batch,让你掌握批处理利器.面对大批量数据毫无惧色.本章只做介绍,后面章节有代码示例.好了,接下来是我们的主角Spring Batch. 1.1 背景介绍 ...
- spring batch (一) 常见的基本的概念介绍
SpringBatch的基本概念介绍 内容来自<Spring Batch 批处理框架>,作者:刘相. 一.配置文件 在项目中使用spring batch 需要在配置文件中声明: 事务管理器 ...
随机推荐
- hdu 4565 So Easy!(矩阵+快速幂)
题目大意:就是给出a,b,n,m:让你求s(n); 解题思路:因为n很可能很大,所以一步一步的乘肯定会超时,我建议看代码之前,先看一下快速幂和矩阵快速幂,这样看起来就比较容易,这里我直接贴别人的推导, ...
- linux c 生成uuid
/********方法一**********/#include <stdio.h> #include <stdlib.h> #include <string.h> ...
- ASP.NET26个性能优化方法
1.数据库访问性能优化 (1)数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源. ASP.NET中提供了连 ...
- Linux常用到的指令汇总
Linux常用到的指令汇总 根据鸟哥linux私房菜上定义的:一定要先學會的指令:ls, more, cd, pwd, rpm, ifconfig, find 登入與登出(開機與關機):telnet, ...
- leetcode:Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- 51nod1084 矩阵取数问题 V2
O(n4)->O(n3)妈呀为什么跑这么慢woc #include<cstdio> #include<cstring> #include<cctype> #i ...
- 对比C++中的指针和引用
指针和引用在形式上比较好区分,由于有很多相似的功能,因此在使用上容易混淆.因此有必要对指针和引用进行对比,以便于在使用时使程序正确高效. 1.引用不可以为空,而指针可以为空. 我们知道引用是对象的别名 ...
- xcode快捷键的使用
1.统计Xcode项目代码行数 1 打开终端. 2 用ls和cd进到你项目的路径. 3 输入下面的指令: grep -r "\n" classes | wc -l (cl ...
- Spark源码阅读(1): Stage划分
Spark中job由action动作生成,那么stage是如何划分的呢?一般的解答是根据宽窄依赖划分.那么我们深入源码看看吧 一个action 例如count,会在多次runJob中传递,最终会到一个 ...
- IPC_共享内存
在IPC(InterProcess Communication)的通信模式下,不管是使用消息队列还是共享内存,甚至是信号量,每个IPC的对象(object)都有唯一的名字,称为“键”(key).通过“ ...