介绍

长话短说,您不应在并行流中使用事务。 这是因为并行流中的每个线程都有其自己的名称,因此它确实参与了事务。

Streams API旨在在某些准则下正常工作。 实际上,为了受益于并行性,不允许每个操作更改共享对象的状态(此类操作称为无副作用)。 如果您遵循此准则,并行流的内部实现将巧妙地拆分数据,将不同部分分配给独立线程,并合并最终结果。

这主要是由于实现事务的方式而产生的。 排序上,ThreadLocal变量用于标记参与事务的每个方法。 ThreadLocal变量无法将其变量保持在并行流中。 为了证明我已经创建了以下测试

 import org.junit.Assert;  import org.junit.Test;  import java.util.concurrent.atomic.AtomicBoolean;  import java.util.stream.IntStream;  public class ThreadNameTest { @Test public void threadLocalTest(){ ThreadContext.set( "MAIN" ); AtomicBoolean hasNamechanged = new AtomicBoolean( false ); IntStream.range( 0 , 10000000 ).boxed().parallel().forEach(n->{ if (! "MAIN" .equals(ThreadContext.get())){ hasNamechanged.set( true ); } }); Assert.assertTrue(hasNamechanged.get()); } private static class ThreadContext { private static ThreadLocal<String> val = ThreadLocal.withInitial(() -> "empty" ); public ThreadContext() { } public static String get() { return val.get(); } public static void set(String x) { ThreadContext.val.set(x); } }  } 

IntStream.range值越高,则测试成功的可能性就越大。

现在看看这个github项目https://github.com/diakogiannis/transactionplayground/

TransactionPlayground项目

我创建了一种以4种不同方式加载猫的服务

  1. 按顺序curl -I -X GET http://localhost:8080/api/cats/all
  2. 顺序但抛出异常以创建回退标记curl -I -X GET http://localhost:8080/api/cats/all-exception
  3. 在并行curl -I -X GET http://localhost:8080/api/cats/all-parallel
  4. 并行但抛出异常以创建回退标记curl -I -X GET http://localhost:8080/api/cats/all-parallel-exception

也有2个辅助呼叫

  1. 清理curl -I -X DELETE http://localhost:8080/api/cats/
  2. 和一个实际查看猫的curl -X GET http://localhost:8080/api/cats/

开始项目

请执行mvn clean package wildfly-swarm:run

正常订购

呼叫curl -I -X GET http://localhost:8080/api/cats/all ,然后curl -X GET http://localhost:8080/api/cats/

正常,无订单,又称平行

调用clean curl -I -X DELETE http://localhost:8080/api/cats/调用curl -I -X GET http://localhost:8080/api/cats/all-parallel然后curl -X GET http://localhost:8080/api/cats/

预期的结果是看到猫的清单。 无需订购。 这就是为什么并行流先到先服务并从列表中随机读取的原因。

正常,例外

调用clean curl -I -X DELETE http://localhost:8080/api/cats/调用curl -I -X GET http://localhost:8080/api/cats/all-exception然后curl -X GET http://localhost:8080/api/cats/

预期的结果是一个空列表。 这是因为该事务被标记为回滚,所以jdbc事务也被回滚,因此所有条目都没有按照ACID模型持久化到数据库中。

平行例外

调用clean curl -I -X DELETE http://localhost:8080/api/cats/调用curl -I -X GET http://localhost:8080/api/cats/all-parallel-exception然后curl -X GET http://localhost:8080/api/cats/

预期的结果不是一个空列表。 这是因为并行流中的每个线程都会打开自己的jdbc事务,并在完成后进行提交。 因此,每次执行此操作时,都会显示一些猫,直到出现异常并停止执行为止。 回滚仅在一个线程中进行。

翻译自: https://www.javacodegeeks.com/2019/09/should-parallel-streams-transaction-context.html

我可以/应该在事务上下文中使用并行流吗?相关推荐

  1. 只读事务上下文_我可以/应该在事务上下文中使用并行流吗?

    只读事务上下文 介绍 长话短说,您不应在并行流中使用事务. 这是因为并行流中的每个线程都有其自己的名称,因此它确实参与了事务. Streams API旨在在某些准则下正常工作. 实际上,为了受益于并行 ...

  2. Java SE 8新功能介绍:使用Streams API处理集合

    使用Java SE 8 Streams的代码更干净,易读且功能强大..... 在" Java SE 8新功能介绍"系列的这篇文章中,我们将深入解释和探索代码,以了解如何使用流遍历集 ...

  3. Spring事务管理 与 SpringAOP

    1,Spring事务的核心接口 Spring事务管理的实现有许多细节,如果对整个接口框架有个大体了解会非常有利于我们理解事务,下面通过讲解Spring的事务接口来了解Spring实现事务的具体策略.  ...

  4. 一文带你看懂Spring事务!

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 前言 Spring事务管理我相信大家都用得很多,但可能仅仅局限于一个@Transactiona ...

  5. 分布式事务篇——第二章:分布式事务解决之2PC剖析

    前面已经学习了分布式事务的基础理论,以理论为基础,针对不同的分布式场景业界常见的解决方案有2PC. TCC.可靠消息最终一致性.最大努力通知这几种.本文主要着重剖析2PC的方案和落地!! 1.什么是2 ...

  6. Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

  7. 阿里开源分布式事务解决方案 Fescar 全解析

    广为人知的阿里分布式事务解决方案:GTS(Global Transaction Service),已正式推出开源版本,取名为"Fescar",希望帮助业界解决微服务架构下的分布式事 ...

  8. Spring 事务管理高级应用难点剖析

    Spring 事务管理高级应用难点剖析: 第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-spring-ts1/index.html htt ...

  9. springboot mysql 事务_springBoot(14):使用SQL关系型数据库-事务处理

    一.事务的四个特性(ACID) 原子性(Atomicity): 事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用. 一致性(Consistency): 一旦事务 ...

最新文章

  1. python自学什么书比较好-如何自学Python ?自学看什么书比较好?
  2. bzoj - 2038: [2009国家集训队]小Z的袜子(hose)
  3. php 域名验证系统_PHP授权验证系统(域名+IP双重验证一键更新授权系统)
  4. c#日期转换周几_RPA经验:使用 selector 选择日期
  5. hdu 2188巴什博弈
  6. Oracle分页查询格式(八)
  7. git merge和git merge --no-ff有什么区别?
  8. WebUI Case(1): www.swt-designer.com 首页
  9. canvas压缩图片成base64,传到后台解码需要注意的问题
  10. 经典C语言学习教程资料
  11. 线性规划专题——Lingo的使用
  12. 方正计算机如何用u盘安装系统,方正电脑用u盘装系统操作方法
  13. sybase数据库导出mysql_sybase数据库导出表结构
  14. python自动生成sql建表语句
  15. 通俗易懂的粒子滤波算法(PF)
  16. Unity3D正交-透视混合相机的实现
  17. 对ashx请求用Gzip,Deflated压缩
  18. 深度学习GPU选购指南:哪款显卡配得上我的炼丹炉?
  19. spark中的cache()、persist()和checkpoint()的区别
  20. FPGA学习思考过程记录:一

热门文章

  1. codeforces1208 F. Bits And Pieces(SOS DP)
  2. 【图论】【最短路】【Dijkstra】最小花费(ssl 2206/luogu 1576)
  3. 【动态规划】书的复制 (ssl 1203)
  4. CF1088F Ehab and a weird weight formula(树上最优性问题、贪心+倍增)
  5. UVA4671 K-neighbor substrings FFT+字符串hash
  6. Javafx的WebEngine的url加载不输出结果坑,gc回收了局部变量
  7. Redis 常用操作命令,非常详细
  8. Java Web应用的代码分层最佳实践
  9. laravel如何生成swagger接口文档
  10. 20级:班级日常分享,一天一瞬间