diff --git a/txn.go b/txn.go index c0cb20d67..9212b8130 100644 --- a/txn.go +++ b/txn.go @@ -160,12 +160,12 @@ func (o *oracle) hasConflict(txn *Txn) bool { return false } -func (o *oracle) newCommitTs(txn *Txn) uint64 { +func (o *oracle) newCommitTs(txn *Txn) (uint64, bool) { o.Lock() defer o.Unlock() if o.hasConflict(txn) { - return 0 + return 0, true } var ts uint64 @@ -194,7 +194,7 @@ func (o *oracle) newCommitTs(txn *Txn) uint64 { }) } - return ts + return ts, false } func (o *oracle) doneRead(txn *Txn) { @@ -557,10 +557,8 @@ func (txn *Txn) commitAndSend() (func() error, error) { orc.writeChLock.Lock() defer orc.writeChLock.Unlock() - commitTs := orc.newCommitTs(txn) - // The commitTs can be zero if the transaction is running in managed mode. - // Individual entries might have their own timestamps. - if commitTs == 0 && !txn.db.opt.managedTxns { + commitTs, conflict := orc.newCommitTs(txn) + if conflict { return nil, ErrConflict } diff --git a/txn_test.go b/txn_test.go index 021f74b26..9823a9cff 100644 --- a/txn_test.go +++ b/txn_test.go @@ -817,6 +817,15 @@ func TestManagedDB(t *testing.T) { } } txn.Discard() + + // Write data to same key, causing a conflict + txn = db.NewTransactionAt(10, true) + txnb := db.NewTransactionAt(10, true) + txnb.Get(key(0)) + require.NoError(t, txn.SetEntry(NewEntry(key(0), val(0)))) + require.NoError(t, txnb.SetEntry(NewEntry(key(0), val(1)))) + require.NoError(t, txn.CommitAt(11, nil)) + require.Equal(t, ErrConflict, txnb.CommitAt(11, nil)) } t.Run("disk mode", func(t *testing.T) { db, err := Open(opt)