diff --git a/index/store/boltdb/writer.go b/index/store/boltdb/writer.go index 7c16c8ae..0c0f9b48 100644 --- a/index/store/boltdb/writer.go +++ b/index/store/boltdb/writer.go @@ -27,7 +27,7 @@ func (w *Writer) NewBatchEx(options store.KVBatchOptions) ([]byte, store.KVBatch return make([]byte, options.TotalBytes), w.NewBatch(), nil } -func (w *Writer) ExecuteBatch(batch store.KVBatch) error { +func (w *Writer) ExecuteBatch(batch store.KVBatch) (err error) { emulatedBatch, ok := batch.(*store.EmulatedBatch) if !ok { @@ -36,10 +36,23 @@ func (w *Writer) ExecuteBatch(batch store.KVBatch) error { tx, err := w.store.db.Begin(true) if err != nil { - return err + return } + // defer function to ensure that once started, + // we either Commit tx or Rollback + defer func() { + // if nothing went wrong, commit + if err == nil { + // careful to catch error here too + err = tx.Commit() + } else { + // caller should see error that caused abort, + // not success or failure of Rollback itself + tx.Rollback() + } + }() defer tx.Rollback() - + bucket := tx.Bucket([]byte(w.store.bucket)) bucket.FillPercent = w.store.fillPercent @@ -48,29 +61,29 @@ func (w *Writer) ExecuteBatch(batch store.KVBatch) error { existingVal := bucket.Get(kb) mergedVal, fullMergeOk := w.store.mo.FullMerge(kb, existingVal, mergeOps) if !fullMergeOk { - return fmt.Errorf("merge operator returned failure") + err = fmt.Errorf("merge operator returned failure") + return } err = bucket.Put(kb, mergedVal) if err != nil { - return err + return } } for _, op := range emulatedBatch.Ops { if op.V != nil { - err := bucket.Put(op.K, op.V) + err = bucket.Put(op.K, op.V) if err != nil { - return err + return } } else { - err := bucket.Delete(op.K) + err = bucket.Delete(op.K) if err != nil { - return err + return } } } - - return tx.Commit() + return } func (w *Writer) Close() error {