<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:
事情是這樣的:運營人員反饋,通過Excel匯入資料時,有一部分成功了,有一部分未匯入。初步猜測,是事務未生效導致的。檢視程式碼,發現匯入部分已經通過@Transcational註解進行事務控制了,為什麼還會出現事務不生效的問題呢?下面我們就進行具體的案例分析,Let's go!
這裡寫一段簡單的虛擬碼來演示展示一下事務不生效的程式碼:
@Transactional(rollbackFor = Exception.class) public void batchInsert(List<Order> list) { list.parallelStream().forEach(order -> orderMapper.save(order)); }
邏輯很簡單,遍歷list,然後批次插入Order資料到資料庫。在該方法上使用@Transactional來宣告出現異常時進行回滾。
但事實情況是,其中某一條資料執行異常時,事務並沒有進行回滾。這到底是為什麼呢?
下面一探究竟。
上面程式碼中涉及到了兩個知識點:parallelStream和@Transactional,我們先來鋪墊一下parallelStream相關知識。
在JDK8 中引入了Stream API的概念和實現,這裡的Stream有別於 InputStream 和OutputStream,Stream API 是處理物件流而不是位元組流。
比如,我們可以通過如下方式來基於Stream進行實現:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); numbers.stream().forEach(num->System.out.println(num));
輸出:1 2 3 4 5 6 7 8 9
程式碼看起來方便清爽多了。
關於Stream的基本處理流程如下:
在這些Stream API中,還提供了一個並行處理的API,也就是parallelStream。它可以將任務拆分子任務,分發給多個處理器同時處理,之後合併。這樣做的目的很明顯是為了提升處理效率。
parallelStream的基本使用方式如下:
// 並行執行流 list.stream().parallel().filter(e -> e > 10).count()
針對上述程式碼,對應的流程如下:
而parallelStream會將流劃分成多個子流,分散到不同的CPU並行處理,然後合併處理結果。其中,parallelStream預設是基於ForkJoinPool.commonPool()執行緒池來實現並行處理的。
通常情況下,我們可以認為並行會比序列快,但還是有前提條件的:
但並行處理也面臨著一系列的問題,比如:資源競爭、死鎖、執行緒切換、事務、可見性、執行緒安全等問題。
上面瞭解了parallelStream的基本原理及特性之後,再來看看@Transactional的事務處理特性。
@Transactional是Spring提供的基於註解的一種宣告式事務方式,該註解只能運用到public的方法上。
基本原理:當一個方法被@Transactional註解之後,Spring會基於AOP在方法執行之前開啟一個事務。當方法執行完畢之後,根據方法是否報錯,來決定回滾或提交事務。
在預設代理模式下,只有目標方法由外部方法呼叫時,才能被Spring的事務攔截器攔截。所以,在同一個類中的兩個方法直接呼叫,不會被Spring的事務攔截器攔截。這是事務不生效的一個場景,但在上述案例中,並不存在這種情況。
Spring在處理事務時,會從連線池中獲得一個jdbc connection,將連線繫結到執行緒上(基於ThreadLocal),那麼同一個執行緒中用到的就是同一個connection了。具體實現在DataSourceTransactionManager#doBegin方法中。
在瞭解了parallelStream和@Transactional的相關知識之後,我們會發現:parallelStream處理時開啟了多執行緒,而@Transactional在處理事務時會(基於ThreadLocal)將連線繫結到當前執行緒,由於@Transactional繫結管理的是主執行緒的事務,而parallelStream開啟的新的執行緒與主執行緒無關。因此,事務也就無效了。
此時,將parallelStream改為普通的stream,事務可正常回滾。這就提示我們,在使用基於@Transactional方式管理事務時,慎重使用多執行緒處理。
雖然parallelStream帶來了更高的效能,但也要區分場景進行使用。即便是在不需要事務管理的情況下,如果parallelStream使用不當,也會造成同一時間對資料庫發起大量請求等問題。
因此,在stream與parallelStream之間進行選擇時,還要考慮幾個問題:
文章講述的Bug雖然簡單,但如果不瞭解parallelStream與@Transactional註解的特性,還是很難排查的。而且也讓我們意識到,雖然Spring通過@Transactional將事務管理進行了簡化處理,但作為開發者,還是需要深入瞭解一下它的基本運作原理。不然,在排查bug時,很容易踩坑。
到此這篇關於並行Stream與Spring事務相遇會發生什麼?的文章就介紹到這了,更多相關 Stream與Spring 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45