mirror of
https://github.com/luxfi/zapdb.git
synced 2026-07-27 06:54:45 +00:00
fix: Fix conflict detection for managed DB (#1716)
I propose this simple fix for detecting conflicts in managed mode. Addresses https://discuss.dgraph.io/t/fatal-error-when-writing-conflicting-keys-in-managed-mode/14784.
When a write conflict exists for a managed DB, an internal assert can fail.
This occurs because a detected conflict is indicated with commitTs of 0, but handling the error is skipped for managed DB instances.
Rather than conflate conflict detection with a timestamp of 0, it can be indicated with another return value from hasConflict.
(cherry picked from commit 5069c498e4)
This commit is contained in:
committed by
NamanJain8
parent
eea08328e8
commit
64a920f91a
@@ -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) {
|
||||
@@ -537,10 +537,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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user