2. bolt數據庫Update代碼流程分析
在bolt的官方文檔中,關於創建一個讀寫事務的描述如下:
Read-write transactions
To start a read-write transaction, you can use the DB.Update()
function:
err := db.Update(func(tx *bolt.Tx) error {
...
return nil
})
Inside the closure, you have a consistent view of the database. You commit the
transaction by returning nil
at the end. You can also rollback the transaction
at any point by returning an error. All database operations are allowed inside
a read-write transaction.
Always check the return error as it will report any disk failures that can cause
your transaction to not complete. If you return an error within your closure
it will be passed through.
在源碼中func (db *DB) Update(fn func(*Tx) error) error { }
將fn作爲變量傳入,並完成增刪改查一系列操作。
Update
首先調用db.Begin(true)
來獲取讀寫鎖並返回一個讀寫類型的事務指針。Begin內部還會調用beginRWTx()
以執行獲取鎖的操作並釋放已關閉的事務關聯的頁面。
函數內部還defer了一個匿名函數以執行事務處理失敗後的回滾操作。
// Make sure the transaction rolls back in the event of a panic.
defer func() {
if t.db != nil {
t.rollback()
}
}()
接下來執行了用戶傳入fn函數,並通過標記t.managed
以防止用戶進行提交操作。
// Mark as a managed tx so that the inner function cannot manually commit.
t.managed = true
// If an error is returned from the function then rollback and return error.
err = fn(t)
t.managed = false
最後會調用tx.commit()
,並返回提交結果給用戶。
關於blotdb相關的數據結構和算法,推薦閱讀區塊的持久化之BoltDB(一)到(五的系列文章。