code: func (txn *Txn) Commit() {
  	// Noop for a read transaction
  	if !txn.write {
  		return
  	}
  
  	// Check if already aborted or committed
  	if txn.rootTxn == nil {
  		return
  	}
  
  	// Commit each sub-transaction scoped to (table, index)
  	for key, subTxn := range txn.modified {
  		path := indexPath(key.Table, key.Index)
  		final := subTxn.CommitOnly()
  		txn.rootTxn.Insert(path, final)
  	}
  
  	// Update the root of the DB
  	newRoot := txn.rootTxn.CommitOnly()
  	atomic.StorePointer(&txn.db.root, unsafe.Pointer(newRoot))
  
  	// Now issue all of the mutation updates (this is safe to call
  	// even if mutation tracking isn't enabled); we do this after
  	// the root pointer is swapped so that waking responders will
  	// see the new state.
  	for _, subTxn := range txn.modified {
  		subTxn.Notify()
  	}
  	txn.rootTxn.Notify()
  
  	// Clear the txn
  	txn.rootTxn = nil
  	txn.modified = nil
  
  	// Release the writer lock since this is invalid
  	txn.db.writer.Unlock()
  
  	// Run the deferred functions, if any
  	for i := len(txn.after); i > 0; i-- {
  		fn := txn.after[i-1]
  		fn()
  	}
  }
docs: // Commit is used to finalize this transaction.
  // This is a noop for read transactions.