java – Spring无法将事务传播到ForkJoin的RecursiveAction
我正在尝试实现一个多线程解决方案,以便我可以并行化我的业务逻辑,包括读取和写入数据库.
技术堆栈:Spring 4.0.2,Hibernate 4.3.8 以下是一些要讨论的代码: 组态 @Configuration public class PartitionersConfig { @Bean public ForkJoinPoolFactoryBean forkJoinPoolFactoryBean() { final ForkJoinPoolFactoryBean poolFactory = new ForkJoinPoolFactoryBean(); return poolFactory; } } 服务 @Service @Transactional public class MyService { @Autowired private OtherService otherService; @Autowired private ForkJoinPool forkJoinPool; @Autowired private MyDao myDao; public void performPartitionedActionOnIds() { final ArrayList<UUID> ids = otherService.getIds(); MyIdPartitioner task = new MyIdsPartitioner(ids,myDao,ids.size() - 1); forkJoinPool.invoke(task); } } 存储库/ DAO @Repository @Transactional(propagation = Propagation.MANDATORY) public class IdsDao { public MyData getData(List<UUID> list) { // ... } } RecursiveAction public class MyIdsPartitioner extends RecursiveAction { private static final long serialVersionUID = 1L; private static final int THRESHOLD = 100; private ArrayList<UUID> ids; private int fromIndex; private int toIndex; private MyDao myDao; public MyIdsPartitioner(ArrayList<UUID> ids,MyDao myDao,int fromIndex,int toIndex) { this.ids = ids; this.fromIndex = fromIndex; this.toIndex = toIndex; this.myDao = myDao; } @Override protected void compute() { if (computationSetIsSamllEnough()) { computeDirectly(); } else { int leftToIndex = fromIndex + (toIndex - fromIndex) / 2; MyIdsPartitioner leftPartitioner = new MyIdsPartitioner(ids,fromIndex,leftToIndex); MyIdsPartitioner rightPartitioner = new MyIdsPartitioner(ids,leftToIndex + 1,toIndex); invokeAll(leftPartitioner,rightPartitioner); } } private boolean computationSetIsSamllEnough() { return (toIndex - fromIndex) < THRESHOLD; } private void computeDirectly() { final List<UUID> subList = ids.subList(fromIndex,toIndex); final MyData myData = myDao.getData(sublist); modifyTheData(myData); } private void modifyTheData(MyData myData) { // ... // write to DB } } 执行此操作后,我得到:
我理解这是完全正常的,因为事务不会通过不同的线程传播.因此,一个解决方案是在每个线程as proposed in another similar question中手动创建一个事务.但这对我来说不够令人满意,所以我一直在搜索. 在Spring的论坛中我找到了a discussion on the topic.我发现一段非常有趣:
因此,第一个问题出现了:是否值得对数据库的读/写进行简化,这是否真的会损害数据库的一致性? 解决方法
这应该可以使用atomikos(
http://www.atomikos.com)并可选择使用嵌套事务.
如果这样做,那么如果同一根事务的多个线程写入数据库中的相同表,请注意避免死锁. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |