Commit commits the transaction, following these steps: 1. If there are no writes, return immediately. 2. Check if read rows were updated since txn started. If so, return ErrConflict. 3. If no conflict, generate a commit timestamp and update written rows' commit ts. 4. Batch up all writes, write
()
| 653 | // If error is nil, the transaction is successfully committed. In case of a non-nil error, the LSM |
| 654 | // tree won't be updated, so there's no need for any rollback. |
| 655 | func (txn *Txn) Commit() error { |
| 656 | // txn.conflictKeys can be zero if conflict detection is turned off. So we |
| 657 | // should check txn.pendingWrites. |
| 658 | if len(txn.pendingWrites) == 0 { |
| 659 | return nil // Nothing to do. |
| 660 | } |
| 661 | // Precheck before discarding txn. |
| 662 | if err := txn.commitPrecheck(); err != nil { |
| 663 | return err |
| 664 | } |
| 665 | defer txn.Discard() |
| 666 | |
| 667 | txnCb, err := txn.commitAndSend() |
| 668 | if err != nil { |
| 669 | return err |
| 670 | } |
| 671 | // If batchSet failed, LSM would not have been updated. So, no need to rollback anything. |
| 672 | |
| 673 | // TODO: What if some of the txns successfully make it to value log, but others fail. |
| 674 | // Nothing gets updated to LSM, until a restart happens. |
| 675 | return txnCb() |
| 676 | } |
| 677 | |
| 678 | type txnCb struct { |
| 679 | commit func() error |