From 9354dac52ed28eb16d0e8e1835759b23d1583992 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Fri, 25 Jun 2021 19:27:18 +0800 Subject: [PATCH 1/2] Managed DB conflict test case --- txn_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) 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) From adf46d855e80e8152b62be26692d4a74a5e7c8ed Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Fri, 25 Jun 2021 19:38:19 +0800 Subject: [PATCH 2/2] Fix conflict handling for managed DB --- txn.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) 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 }