日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/3 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我可以/应该在事务上下文中使用并行流吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

介紹

長話短說,您不應在并行流中使用事務。 這是因為并行流中的每個線程都有其自己的名稱,因此它確實參與了事務。

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種不同方式加載貓的服務

  • 按順序curl -I -X GET http://localhost:8080/api/cats/all
  • 順序但拋出異常以創建回退標記curl -I -X GET http://localhost:8080/api/cats/all-exception
  • 在并行curl -I -X GET http://localhost:8080/api/cats/all-parallel
  • 并行但拋出異常以創建回退標記curl -I -X GET http://localhost:8080/api/cats/all-parallel-exception
  • 也有2個輔助呼叫

  • 清理curl -I -X DELETE http://localhost:8080/api/cats/
  • 和一個實際查看貓的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

    總結

    以上是生活随笔為你收集整理的我可以/应该在事务上下文中使用并行流吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。