事務簡介
事務是資料庫中處理的邏輯單元,每個事務中包括一個或多個資料庫操作,既可以是讀操作,也可以是寫操作,
ACID 是一個“真正”事務所需要具備的一組屬性集合,指的是原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability),
原子性指的是,事務中的所有操作要么都被應用,要么都不被應用,
一致性指的是,如果資料庫在執行事務之前是一致性狀態,那么在事務執行之后,無論事務是否成功,資料庫也應該是一致性狀態,
隔離性指的是,即使資料庫中有多個事務并發地執行,各個事務之間也不會互相影響,并且在并發狀態下執行的事務和串行執行的事務產生的結果完全相同,
持久性指的是,在事務成功提交了之后,事務所變更的資料一定會保存起來,而不會因為任何故障導致資料丟失,
當資料庫滿足所有這些屬性,并且只有成功的事務才會被處理時,它就被稱為是符合 ACID 的資料庫,
如何使用事務
事務語法
MongoDB 提供了兩種 API 來使用事務:
- 核心 API,與關系資料庫類似的語法(如
start_transaction和commit_transaction) - 回呼 API,這是使用事務的推薦方法
核心 API 不為大多數錯誤提供重試邏輯,它要求開發人員為操作、事務提交函式以及所需的任何重試和錯誤邏輯手動撰寫代碼,
與核心 API 不同,回呼 API 提供了一個單獨的函式,該函式封裝了大量功能,包括啟動與指定邏輯會話關聯的事務、執行作為回呼函式提供的函式以及提交事務(或在出現錯誤時中止),此函式還包含了處理提交錯誤的重試邏輯,
在 MongoDB 4.2 中添加回呼 API 是為了簡化使用事務的應用程式開發,也便于添加處理事務錯誤的應用程式重試邏輯,
API 區別
| 核心 API | 回呼 API |
|---|---|
| 需要顯式呼叫才能啟動和提交事務 | 啟動事務、執行指定的操作,然后提交(或在發生錯誤時終止) |
不包含 TransientTransactionError 和 UnknownTransactionCommitResult 的錯誤處理邏輯,而是提供了為這些錯誤進行自定義處理的靈活性 |
自動為 TransientTransactionError 和 UnknownTransactionCommitResult 提供錯誤處理邏輯 |
| 要求為特定事務將顯式的邏輯會話傳遞給 API | 要求為特定事務將顯式的邏輯會話傳遞給 API |
實際使用
在一個 Python 的例子當中,使用核心 API 的偽代碼如下展示:
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure, OperationFailure
# 顯式開啟一個事務會話
with client.start_session() as session:
while True:
try:
with session.start_transaction():
# 執行事務中的多個寫操作
pass
# 提交事務
session.commit_transaction()
except (ConnectionFailure, OperationFailure) as e:
# 錯誤處理
if e.has_error_label("UnknownTransactionCommitResult"):
# 出現暫時性錯誤,則重試整個事務
continue
else:
raise
使用核心 API 需要注意錯誤的捕捉和處理,而回呼 API 就不需要注意這些,其偽代碼如下展示:
from pymongo import MongoClient
def session_callback(session):
# 執行事務中的多個寫操作
pass
# 顯式開啟一個事務會話
with client.start_session() as session:
session.with_transaction(session_callback)
事務調優
在使用事務時,有幾個重要的引數需要注意,可以對它們進行調整,以確保應用程式能夠最佳地使用事務,
在 MongoDB 事務中有兩類主要的限制:
- 第一類與事務的時間限制有關,控制特定事務可以運行多長時間、事務等待獲取鎖的時間以及所有事務將運行的最大長度
- 第二類與 MongoDB 的 oplog 條目和單個條目的大小限制有關
時間限制
事務的默認最大運行時間是 1 分鐘,
可以通過在 mongod 實體級別上修改 transactionLifetimeLimitSeconds 的限制來增加,對于分片集群,必須在所有分片副本集成員上設定該引數,超過此時間后,事務將被視為已過期,并由定期運行的清理行程中止,清理行程每 60 秒或每 transactionLifetimeLimitSeconds/2 運行一次,以較小的值為準,
要顯式設定事務的時間限制,建議在提交事務時指定 maxTimeMS 引數,實際上會使用 maxTimeMS 和 transactionLifetimeLimitSeconds 中的更小值,
事務等待獲取其操作所需鎖的默認最大時間是 5 毫秒,可以通過修改由 maxTransactionLockRequestTimeoutMillis 引數控制的限制來增加,如果事務在此期間無法獲得鎖,則該事務會被中止,
當 maxTransactionLockRequestTimeoutMillis 設定為 0 時,意味著如果事務無法立即獲得所需的所有鎖,則該事務會被中止,設定為 -1 將使用由 maxTimeMS 引數所指定的特定于操作的超時時間,
oplog 大小限制
MongoDB 會創建出與事務中寫運算元量相同的 oplog 條目,
但是,每個 oplog 條目必須在 16MB 的 BSON 檔案大小限制之內,
首發于「程式員翔仔」,點擊查看更多,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/538417.html
標籤:其他
