我有一个java批处理项目,其中一些数据对象(在oracle-db中持久化)被修改(几次修改(不是一次;因为它们太复杂,无法填充到一个db-udpate中,并且因为它们更新了几个表)。
到目前为止,我使用了spring(包括org.springframework.jdbc.datasource.DataSourceTransactionManager). )。我不得不从'old‘迁移(java6,旧库(比如Spring3.1,.))和maven)我们的“新的方法”(java8,更新的库(如Spring4.3.7,.)和)..。而移民则是一种偶然的替代(以一种低级的方式;-)
(到目前为止,唯一的代码更改是,在遇到错误后,我已经改变了服务--函数被注释为事务性的方式(通过添加传播REQUIRES_NEW),但这并没有修复它(但我保留了它,因为它看起来很好,可以记录传播,而不是依赖默认值)。
但是当我测试这个批处理时,我注意到(到目前为止没有任何代码更改).事务处理失败(与“旧”版本相比)。
各批次主要结构的相关部分如下:
BatchRunner {
public static int main(int, String) { ... }
|
--> calls via injected object
}
@Component
ProcessorService {
@Override
public void someProcessingStep()
|
---> selects all 'data-objects'; iterates over them and calls via injected object (DataCalculator.someMethod())
}
@Component
DataCalculator {
@Override
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)
public void someMethod()
|
---> does some calculation; updates; further selects; more calculation; and some final updates to various tables
}虽然ProcessorService不是事务性的(无论是在类级别上还是在方法级别上);但是DataCalculator的方法'someMethod' (通过注入对象调用)应该是.但是如果其中有10个更新.而第7次失败.通常程序回滚所有已经完成的更新.但不是使用我的spring-4.3.7迁移版本。(提示:只涉及一个数据库/连接;这不是XA问题)。
当然,DataCalculator的'someMethod'稍微复杂一些,它有时捕获、有时捕获和重新抛出Exceptions.但是,一旦一些Exception (或Exception派生类)‘停止’'someMethod'的执行,我就会期望数据库上所做的一切(在这个‘注入’调用中)都会被回滚.所以它是..。在移民之前。
请你分享一些我能找到我的bug的光线(因为我不认为这是框架相关的东西.这是我使用它的错误方式)。
如果你需要更多关于这个问题的信息,请告诉我。(我将更新这个问题,以澄清问题;我只是想保持最初的帖子尽可能小。)
发布于 2018-02-12 11:10:45
使用propagation=Propagation.REQUIRES_NEW时,DataCalculator.someMethod()的每个调用都会有一个新的事务,该事务将在离开方法后完成。
如果有10次更新的话.第七次失败..。
6个更新将出现在6个不同的事务中,它们将被提交,但是会抛出一个异常。
如果您想在一起进行所有更新(=在一个事务中)--用ProcessorService.someProcessingStep标记@Transactional (与任何传播),并将DataCalculator.someMethod()的传播更改为Propagation.REQUIRES (它是默认值)。
所需的支持当前事务,如果不存在,则创建新事务。 REQUIRES_NEW创建一个新事务,如果存在当前事务,则挂起当前事务。
发布于 2018-02-15 18:45:46
我终于发现了我真正的问题是什么--我们的集成测试使我陷入了错误的思维方向,认为它与事务处理有关。
真正的问题是,我的DTO一开始写得很好,后来读到了一些缺少的专栏.然后那些不完整的DTO正在覆盖原来存储的DTO。
(缺失部分列中的bug是在Spring4.2中引入的,其中BeanPropertyRowMapper的initialize()函数被更改为处理与以前不同的'foo_bar_1‘这样的列。)
https://stackoverflow.com/questions/48744699
复制相似问题