精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

認識MongoDB 4.0的新特性——事務(Transactions)

數據庫 其他數據庫 MongoDB
以前 MongoDB 是不支持事務的,因此開發者在需要用到事務的時候,不得不借用其他工具,在業務代碼層面去彌補數據庫的不足。隨著 4.0 版本的發布,MongoDB 也為我們帶來了原生的事務操作,下面就讓我們一起來認識它,并通過簡單的例子了解如何去使用。

前言

相信使用過主流的關系型數據庫的朋友對“事務(Transactions)”不會太陌生,它可以讓我們把對多張表的多次數據庫操作整合為一次原子操作,這在高并發場景下可以保證多個數據操作之間的互不干擾;并且一旦在這些操作過程任一環節中出現了錯誤,事務會中止并且讓數據回滾,這使得同時在多張表中修改數據的時候保證了數據的一致性。

以前 MongoDB 是不支持事務的,因此開發者在需要用到事務的時候,不得不借用其他工具,在業務代碼層面去彌補數據庫的不足。隨著 4.0 版本的發布,MongoDB 也為我們帶來了原生的事務操作,下面就讓我們一起來認識它,并通過簡單的例子了解如何去使用。

 

 

 

[[249466]]

 

介紹

事務和副本集(Replica Sets)

副本集是 MongoDB 的一種主副節點架構,它使數據得到***的可用性,避免單點故障引起的整個服務不能訪問的情況的發生。目前 MongoDB 的多表事務操作僅支持在副本集上運行,想要在本地環境安裝運行副本集可以借助一個工具包——run-rs,以下的文章中有詳細的使用說明:

https://thecodebarbarian.com/...

事務和會話(Sessions)

事務和會話(Sessions)關聯,一個會話同一時刻只能開啟一個事務操作,當一個會話斷開,這個會話中的事務也會結束。

事務中的函數

  • Session.startTransaction()

在當前會話中開始一次事務,事務開啟后就可以開始進行數據操作。在事務中執行的數據操作是對外隔離的,也就是說事務中的操作是原子性的。

  • Session.commitTransaction()

提交事務,將事務中對數據的修改進行保存,然后結束當前事務,一次事務在提交之前的數據操作對外都是不可見的。

  • Session.abortTransaction()

中止當前的事務,并將事務中執行過的數據修改回滾。

重試

當事務運行中報錯,catch 到的錯誤對象中會包含一個屬性名為 errorLabels 的數組,當這個數組中包含以下2個元素的時候,代表我們可以重新發起相應的事務操作。

  • TransientTransactionError:出現在事務開啟以及隨后的數據操作階段
  • UnknownTransactionCommitResult:出現在提交事務階段

示例

經過上面的鋪墊,你是不是已經迫不及待想知道究竟應該怎么寫代碼去完成一次完整的事務操作?下面我們就簡單寫一個例子:

場景描述: 假設一個交易系統中有2張表——記錄商品的名稱、庫存數量等信息的表 commodities,和記錄訂單的表 orders。當用戶下單的時候,首先要找到 commodities 表中對應的商品,判斷庫存數量是否滿足該筆訂單的需求,是的話則減去相應的值,然后在 orders 表中插入一條訂單數據。在高并發場景下,可能在查詢庫存數量和減少庫存的過程中,又收到了一次新的創建訂單請求,這個時候可能就會出問題,因為新的請求在查詢庫存的時候,上一次操作還未完成減少庫存的操作,這個時候查詢到的庫存數量可能是充足的,于是開始執行后續的操作,實際上可能上一次操作減少了庫存后,庫存的數量就已經不足了,于是新的下單請求可能就會導致實際創建的訂單數量超過庫存數量。

以往要解決這個問題,我們可以用給商品數據“加鎖”的方式,比如基于 Redis 的各種鎖,同一時刻只允許一個訂單操作一個商品數據,這種方案能解決問題,缺點就是代碼更復雜了,并且性能會比較低。如果用數據庫事務的方式就可以簡潔很多:

commodities 表數據(stock 為庫存):

 

  1. "_id" : ObjectId("5af0776263426f87dd69319a"), "name" : "滅霸原味手套""stock" : 5 } 
  2. "_id" : ObjectId("5af0776263426f87dd693198"), "name" : "雷神專用鐵錘""stock" : 2 } 

 

orders 表數據:

 

  1. "_id" : ObjectId("5af07daa051d92f02462644c"), "commodity": ObjectId("5af0776263426f87dd69319a"), "amount": 2 } 
  2. "_id" : ObjectId("5af07daa051d92f02462644b"), "commodity": ObjectId("5af0776263426f87dd693198"), "amount": 3 } 

 

通過一次事務完成創建訂單操作(mongo Shell):

 

  1. // 執行 txnFunc 并且在遇到 TransientTransactionError 的時候重試 
  2. function runTransactionWithRetry(txnFunc, session) { 
  3.   while (true) { 
  4.     try { 
  5.       txnFunc(session); // 執行事務 
  6.       break; 
  7.     } catch (error) { 
  8.       if ( 
  9.         error.hasOwnProperty('errorLabels') && 
  10.         error.errorLabels.includes('TransientTransactionError'
  11.       ) { 
  12.         print('TransientTransactionError, retrying transaction ...'); 
  13.         continue
  14.       } else { 
  15.         throw error; 
  16.       } 
  17.     } 
  18.   } 
  19.  
  20. // 提交事務并且在遇到 UnknownTransactionCommitResult 的時候重試 
  21. function commitWithRetry(session) { 
  22.   while (true) { 
  23.     try { 
  24.       session.commitTransaction(); 
  25.       print('Transaction committed.'); 
  26.       break; 
  27.     } catch (error) { 
  28.       if ( 
  29.         error.hasOwnProperty('errorLabels') && 
  30.         error.errorLabels.includes('UnknownTransactionCommitResult'
  31.       ) { 
  32.         print('UnknownTransactionCommitResult, retrying commit operation ...'); 
  33.         continue
  34.       } else { 
  35.         print('Error during commit ...'); 
  36.         throw error; 
  37.       } 
  38.     } 
  39.   } 
  40.  
  41. // 在一次事務中完成創建訂單操作 
  42. function createOrder(session) { 
  43.   var commoditiesCollection = session.getDatabase('mall').commodities; 
  44.   var ordersCollection = session.getDatabase('mall').orders; 
  45.   // 假設該筆訂單中商品的數量 
  46.   var orderAmount = 3; 
  47.   // 假設商品的ID 
  48.   var commodityID = ObjectId('5af0776263426f87dd69319a'); 
  49.  
  50.   session.startTransaction({ 
  51.     readConcern: { level'snapshot' }, 
  52.     writeConcern: { w: 'majority' }, 
  53.   }); 
  54.  
  55.   try { 
  56.     var { stock } = commoditiesCollection.findOne({ _id: commodityID }); 
  57.     if (stock < orderAmount) { 
  58.       print('Stock is not enough'); 
  59.       session.abortTransaction(); 
  60.       throw new Error('Stock is not enough'); 
  61.     } 
  62.     commoditiesCollection.updateOne( 
  63.       { _id: commodityID }, 
  64.       { $inc: { stock: -orderAmount } } 
  65.     ); 
  66.     ordersCollection.insertOne({ 
  67.       commodity: commodityID, 
  68.       amount: orderAmount, 
  69.     }); 
  70.   } catch (error) { 
  71.     print('Caught exception during transaction, aborting.'); 
  72.     session.abortTransaction(); 
  73.     throw error; 
  74.   } 
  75.  
  76.   commitWithRetry(session); 
  77.  
  78. // 發起一次會話 
  79. var session = db.getMongo().startSession({ readPreference: { mode: 'primary' } }); 
  80.  
  81. try { 
  82.   runTransactionWithRetry(createOrder, session); 
  83. } catch (error) { 
  84.   // 錯誤處理 
  85. } finally { 
  86.   session.endSession(); 

 

上面的代碼看著感覺很多,其實 runTransactionWithRetry 和 commitWithRetry 這兩個函數都是可以抽離出來成為公共函數的,不需要每次操作都重復書寫。用上了事務之后,因為事務中的數據操作都是一次原子操作,所以我們就不需要考慮分布并發導致的數據一致性的問題,是不是感覺簡單了許多?

你可能注意到了,代碼中在執行 startTransaction 的時候設置了兩個參數——readConcern 和 writeConcern,這是 MongoDB 讀寫操作的確認級別,在這里用于在副本集中平衡數據讀寫操作的可靠性和性能,如果在這里展開就太多了,所以感興趣的朋友建議去閱讀官方文檔了解一下:

readConcern:

https://docs.mongodb.com/mast...

writeConcern:

https://docs.mongodb.com/mast... 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2009-08-10 18:16:33

ICustomQuer.NET 4.0

2009-08-19 16:51:14

C# 4.0 dyna

2009-09-04 16:28:05

ASP.NET 4.0

2009-05-26 09:28:22

C# 4.0dynamic動態類型

2009-12-30 10:21:36

.NET 4.0

2018-07-05 10:55:25

數據庫MongoDB 4.0多文檔事務

2009-05-26 11:15:31

C# 4.0dynamicVisual Stud

2010-01-05 09:26:13

.NET 4.0

2010-08-17 09:57:39

C#

2010-02-24 14:24:35

.NET 4.0

2009-08-18 09:37:42

ASP.NET 4.0

2011-01-14 10:27:18

C#.netasp.net

2019-08-26 18:45:59

RedisRedis4.0數據庫

2009-07-06 11:00:56

.NET 4.0新特性.NET

2010-05-25 08:34:10

C# 4.0

2009-08-13 09:46:49

C#歷史C# 4.0新特性

2024-08-15 08:00:00

MongoDB數據庫NoSQL

2012-05-18 14:36:50

Fedora 17桌面環境

2009-01-16 10:01:57

MySQL復制特性測試

2012-06-13 01:05:53

JavaRubyJVM
點贊
收藏

51CTO技術棧公眾號

日韩欧美一二三| 国产午夜精品一区二区三区四区| 亚洲国产日韩欧美在线动漫| 欧美在线观看成人| 337p日本欧洲亚洲大胆鲁鲁| 国产精品一区免费在线观看| 26uuu国产精品视频| 日本高清黄色片| theporn国产在线精品| 色综合久久99| 久久99精品久久久久久青青日本 | 国产一级片中文字幕| 国产丝袜在线播放| 国产精品久久久久久久久快鸭 | 欧美视频三区| 一本色道久久综合亚洲91| 欧美欧美一区二区| www.国产黄色| 国产综合精品一区| 在线播放日韩av| 无码任你躁久久久久久老妇| 久久三级毛片| 日韩欧美一区二区在线| 伊人久久在线观看| 91在线品视觉盛宴免费| av不卡免费在线观看| 91美女片黄在线观| avove在线播放| 成人精品影院| 亚洲精品自拍第一页| 久久久九九九热| 日韩av一级| 精品日韩美女的视频高清| 国产精品无码乱伦| 午夜老司机福利| 久久国产视频网| 日本中文字幕久久看| 五月天婷婷网站| 亚洲中无吗在线| 精品国产一区av| av网站免费在线看| 自拍偷拍欧美一区| 日韩久久免费电影| 制服丝袜第一页在线观看| 欧美三级一区| 日韩免费观看高清完整版| 青青艹视频在线| 7777kkk亚洲综合欧美网站| 亚洲丝袜制服诱惑| 麻豆md0077饥渴少妇| 色的视频在线免费看| 国产精品69毛片高清亚洲| 国产免费一区视频观看免费| 九九免费精品视频| 中文字幕一区二区三三| 国产视频久久久久| 自拍视频一区二区| 另类一区二区三区| 欧美精品在线一区二区三区| 一区二区三区欧美精品| 日韩精品第二页| 欧美裸体一区二区三区| 日韩黄色片视频| 特黄毛片在线观看| 日本乱人伦aⅴ精品| 99久久国产宗和精品1上映| 欧洲一区二区三区| 亚洲国产日韩一级| 亚洲一区二区三区加勒比| 国模私拍视频在线| a亚洲天堂av| 97久久精品午夜一区二区| 99视频在线观看免费| 日韩成人伦理电影在线观看| 国产精品爽爽爽| 国产精品毛片一区视频播| 国产成人综合网站| 久久久99爱| 国产98在线| 亚洲日本韩国一区| 国产精品裸体瑜伽视频| 成人在线爆射| 制服丝袜在线91| 亚洲精品一区二区18漫画| 噜噜噜狠狠夜夜躁精品仙踪林| 欧美精品一二三四| 女同性αv亚洲女同志| 激情小说一区| 亚洲最新中文字幕| 欧美做受高潮6| 免费看久久久| 亚洲精品久久久久中文字幕二区| 色欲欲www成人网站| 亚州av日韩av| 久久精品国产一区二区电影| 中文字幕黄色网址| 欧美激情一级片一区二区| 欧洲美女免费图片一区| 国产精品一二三四五区| 99麻豆久久久国产精品免费| 日本一区二区三区视频免费看 | 中文字幕在线观看日韩| 超碰手机在线观看| 香蕉成人久久| 欧美在线一区二区视频| 久久精品国产亚洲AV无码男同 | 日韩电影中文字幕| 日本不卡一区视频| 日韩午夜一区| 亚洲aⅴ日韩av电影在线观看 | 天天操天天干天天操天天干| 一区二区三区四区在线观看国产日韩| 久久躁狠狠躁夜夜爽| 男女啊啊啊视频| 韩国视频一区二区| 日本一区不卡| 欧美裸体视频| 亚洲白虎美女被爆操| 国产黄色片在线| 久久精品一区二区国产| 国产精品一区二区av| 黄色片网站在线观看| 色狠狠av一区二区三区| 亚洲少妇18p| 韩国av一区| 欧美最近摘花xxxx摘花| 动漫av一区二区三区| 国产精品高清亚洲| 天天色综合天天色| 美女少妇全过程你懂的久久| 性色av一区二区三区| 午夜精品久久久久久久第一页按摩| 成人黄色在线视频| 国产对白在线播放| 久久亚洲国产精品尤物| 在线观看欧美日韩国产| 永久久久久久久| 99成人精品| 粉嫩av一区二区三区免费观看| 欧美视频免费一区二区三区| 性久久久久久久| 精品视频站长推荐| 亚洲乱码久久| 久草一区二区| 久久sese| 在线观看日韩专区| 精品乱码一区内射人妻无码| 国产日韩精品一区二区三区| 黄色av免费在线播放| 精品国产亚洲一区二区在线观看 | 91超碰在线电影| 麻豆app在线观看| 91国产精品成人| 极品人妻videosss人妻| 精品999日本| 国产欧美日韩一区| 欧美被日视频| 欧美精品第一页| 波多野结衣家庭教师| 国产在线一区二区| 欧美日韩中文字幕在线播放| 欧美电影院免费观看| 精品中文字幕在线观看| 高清乱码毛片入口| 舔着乳尖日韩一区| 在线免费看v片| 欧美午夜精品一区二区三区电影| 久久久精品久久| 国产普通话bbwbbwbbw| 亚洲综合另类小说| 日本黄色福利视频| 欧美国内亚洲| 精品久久久久久亚洲| 日韩电影免费观看高清完整版| 精品日韩一区二区三区| 国产精品99精品无码视| 国产一区二区三区在线看麻豆 | 午夜精品一区二区三区国产| 亚洲va电影大全| av中文在线资源库| 欧美变态tickle挠乳网站| 国产精品成人国产乱| 久久久久久久久免费| 久久久久久久中文| 日韩在线观看电影完整版高清免费悬疑悬疑 | 中国毛片在线观看| 蜜桃一区二区三区在线| 日韩精品一区二区在线视频| 精品中文在线| 久久久国产91| 日韩精品123| 91精品欧美一区二区三区综合在 | 欧美综合久久| 97神马电影| 成人免费福利| 美女精品视频一区| 国产中文字幕在线看| 欧美一二三在线| 日韩中文字幕在线观看视频| 成人h精品动漫一区二区三区| 日产中文字幕在线精品一区| 国产精品va视频| 日韩美女在线观看一区| av理论在线观看| 国产一区二区三区在线播放免费观看 | 国产成人久久精品| 日韩激情av| 在线播放国产一区中文字幕剧情欧美| www.五月婷婷.com| 亚洲午夜精品在线| 在线观看日韩精品视频| 国产精品一区专区| 麻豆三级在线观看| 亚洲欧美视频| 亚洲欧美国产一区二区| 精品国产导航| 99视频国产精品免费观看| 国产美女久久| 国产91色在线免费| 国产黄在线播放| 亚洲激情久久久| 国产夫妻自拍av| 欧美日韩不卡视频| 一区二区三区麻豆| 色综合中文字幕| 久久久久久久久久久久久av| 亚洲香肠在线观看| av直播在线观看| 成人黄色综合网站| 国产乱国产乱老熟300部视频| 香蕉亚洲视频| 国产极品尤物在线| 波多野结衣在线播放一区| 久久久一本精品99久久精品66| 欧美国产日韩电影| 久久中文字幕视频| 欧美成年黄网站色视频| 色偷偷88888欧美精品久久久| 国产乱淫a∨片免费视频| 欧美日韩一区二区三区在线看| 182在线观看视频| 国产精品网站在线观看| 538精品视频| 国产精品美女久久久久aⅴ| 欧美黄色激情视频| 久久精品免费在线观看| 人妻巨大乳一二三区| 国产高清精品网站| 亚洲黄色a v| 蜜臀国产一区二区三区在线播放| 九九热只有这里有精品| 激情成人综合| 国产青青在线视频| 久久亚洲色图| 在线免费av播放| 青青草91视频| 国产大片一区二区三区| 国产成+人+日韩+欧美+亚洲| 国产女人18毛片水真多18| www日韩大片| 丁香激情五月少妇| 亚洲欧美二区三区| 国产无码精品视频| 91福利国产精品| 日韩乱码一区二区| 亚洲欧美国产77777| 夜夜春很很躁夜夜躁| 亚洲欧美在线观看| 欧美激情国产精品免费| 午夜不卡av免费| 波多野结衣视频免费观看| 天天综合天天做天天综合| 欧美一区二区三区不卡视频| 欧美精品123区| 亚洲经典一区二区三区| 日韩激情av在线播放| 无遮挡动作视频在线观看免费入口| 亚洲精品网址在线观看| 国产精品免费观看| 九九久久精品一区| 三妻四妾完整版在线观看电视剧 | japanese23hdxxxx日韩| 国产精品一区二区三区久久| 综合视频一区| 青青草成人激情在线| 亚洲在线久久| 欧美日韩中文在线视频| 黑人巨大精品欧美一区| 完美搭档在线观看| 国产91精品精华液一区二区三区 | 国产欧美视频一区二区三区| 久久久久久久久免费看无码 | 久久久影院一区二区三区 | 午夜综合激情| 国产真人无码作爱视频免费| 国产一区二区福利视频| 久久国产精品影院| 久久免费电影网| 国产交换配乱淫视频免费| 亚洲视频一区在线观看| 亚洲av中文无码乱人伦在线视色| 欧美午夜精品久久久久久人妖| 在线观看亚洲天堂| 88在线观看91蜜桃国自产| 久久电影中文字幕| 欧美—级高清免费播放| 视频91a欧美| 日本a级片久久久| 亚洲精品九九| 国产999免费视频| 中文字幕乱码日本亚洲一区二区| 黑人操日本美女| 日本乱码高清不卡字幕| 天天色棕合合合合合合合| 久久夜色精品国产欧美乱| 日韩欧美一区二区三区免费观看 | 日韩在线观看免费| 美女日韩欧美| 精品乱子伦一区二区三区| 伊甸园亚洲一区| 久久国产精品网| 日韩中文字幕区一区有砖一区| 高潮一区二区三区| 国产性做久久久久久| 黄网在线观看视频| 亚洲国产精品电影| 超碰97免费在线| 国产精品aaa| 久久91成人| 91传媒久久久| 91一区二区三区在线播放| 久草视频精品在线| 日韩欧美一区二区视频| 国内精品久久久久国产| 国产日韩精品视频| 成人直播大秀| 天天视频天天爽| 中文一区二区在线观看| 亚洲中文字幕在线观看| 色噜噜狠狠狠综合曰曰曰| 国产色a在线| 国产va免费精品高清在线观看| 精品视频在线观看免费观看 | 8050国产精品久久久久久| 久久麻豆视频| 中文字幕在线中文字幕日亚韩一区| 99亚洲一区二区| 艳妇乳肉豪妇荡乳xxx| 性做久久久久久免费观看 | 毛片一区二区| 亚洲永久精品ww.7491进入| 91国模大尺度私拍在线视频| av在线天堂播放| 国产精品一久久香蕉国产线看观看| 久久人人爽人人爽人人片av不| 亚洲在线播放电影| 国产一区二区三区视频在线播放 | 国产精品伦理一区二区| 91中文字幕在线播放| 久久不射电影网| 粉嫩久久久久久久极品| 欧美日韩视频免费在线观看| 国产成人8x视频一区二区| 国产精品免费av一区二区| 亚洲欧美日韩天堂一区二区| 久久国内精品| 超碰10000| 国产伦精一区二区三区| 国产精久久久久久| 日韩视频一区二区| а√天堂8资源中文在线| 欧美三级电影在线播放| 久久精品国产精品亚洲精品| 波多野结衣爱爱视频| 亚洲国产一区二区三区在线观看| 一二三四区在线观看| 国产日韩精品久久| 日韩国产欧美在线视频| 欧洲第一无人区观看| 日韩精品免费观看| 欧洲亚洲精品久久久久| 成年人看的毛片| 国产成人三级在线观看| www.国产com| 久热精品视频在线观看| 视频欧美精品| 二级片在线观看| 久久综合久久综合久久| 国产伦精品一区二区三区视频痴汉| 最近2019中文字幕第三页视频| 国产韩日精品| 欧美国产日韩激情| 国产精品久久久久桃色tv| 天天躁日日躁狠狠躁喷水| 国产一区二区色| 国产亚洲一区在线| 不卡一区二区在线观看| 欧美一区二区啪啪| 亚洲1234区| 男女私大尺度视频|