簽名
func (db *DB) Begin(writable bool) (*Tx, error) {
if writable {
return db.beginRWTx()
}
return db.beginTx()
}
讀寫事務beginRWTx
- 獲取鎖
// Obtain writer lock. This is released by the transaction when it closes.
// This enforces only one writer transaction at a time.
db.rwlock.Lock()
// Once we have the writer lock then we can lock the meta pages so that
// we can set up the transaction.
db.metalock.Lock()
defer db.metalock.Unlock()
rwlock是由transaction釋放的,metalock當前釋放
t := &Tx{writable: true}
t.init(db)
db.rwtx = t
db.freePages()
初始化一個讀寫事務,db.rwtx是一個讀寫事務,db.txs 是隻讀事務。freePages暫時不管,這個需要深入freelist。
只讀事務beginTx
db.metalock.Lock(): 因爲需要修改db的meta data,比如ds.txs
db.mmaplock.RLock(): 寫事務會mmap&flush,讀的時候必須加鎖保證一致性,注意這是個讀寫鎖
db.txs = append(db.txs, t): 加入到txs
db.stats.TxN++;db.stats.OpenTxN = n:只有讀事務纔會有這個數據,因爲寫事務當前只可能有一個
tx init
db.meta().copy(tx.meta): 複製當前的meta,因爲多個tx可以同時進行,db的meta隨時會改變