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(一)到(五的系列文章。