Commit is used to finalize this transaction. This is a noop for read transactions, already aborted or committed transactions.
()
| 131 | // This is a noop for read transactions, |
| 132 | // already aborted or committed transactions. |
| 133 | func (txn *Txn) Commit() { |
| 134 | // Noop for a read transaction |
| 135 | if !txn.write { |
| 136 | return |
| 137 | } |
| 138 | |
| 139 | // Check if already aborted or committed |
| 140 | if txn.rootTxn == nil { |
| 141 | return |
| 142 | } |
| 143 | |
| 144 | // Commit each sub-transaction scoped to (table, index) |
| 145 | for key, subTxn := range txn.modified { |
| 146 | path := indexPath(key.Table, key.Index) |
| 147 | final := subTxn.CommitOnly() |
| 148 | txn.rootTxn.Insert(path, final) |
| 149 | } |
| 150 | |
| 151 | // Update the root of the DB |
| 152 | newRoot := txn.rootTxn.CommitOnly() |
| 153 | atomic.StorePointer(&txn.db.root, unsafe.Pointer(newRoot)) |
| 154 | |
| 155 | // Now issue all of the mutation updates (this is safe to call |
| 156 | // even if mutation tracking isn't enabled); we do this after |
| 157 | // the root pointer is swapped so that waking responders will |
| 158 | // see the new state. |
| 159 | for _, subTxn := range txn.modified { |
| 160 | subTxn.Notify() |
| 161 | } |
| 162 | txn.rootTxn.Notify() |
| 163 | |
| 164 | // Clear the txn |
| 165 | txn.rootTxn = nil |
| 166 | txn.modified = nil |
| 167 | |
| 168 | // Release the writer lock since this is invalid |
| 169 | txn.db.writer.Unlock() |
| 170 | |
| 171 | // Run the deferred functions, if any |
| 172 | for i := len(txn.after); i > 0; i-- { |
| 173 | fn := txn.after[i-1] |
| 174 | fn() |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | // Insert is used to add or update an object into the given table. |
| 179 | // |