-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: Insert on Duplicate Transaction #1289
Comments
Hey @swdee, thank you for raising the issue. This definitely looks odd to me. I'll investigate this further and figure out what's going on. |
@jarifibrahim Have you had a chance to look into this yet? Have you been able to reproduce the issue on your system? |
@swdee It looks like a bug in the iterator to me. I replaced the iterator in your code with func (r *Repo) insert(key int, val string) (bool, error) {
//r.Lock()
//defer r.Unlock()
tx := r.DB.NewTransaction(true)
defer tx.Discard()
e, err := tx.Get(primaryKey(key))
if err == nil && e != nil {
return duplicate, nil
}
// check if key exists before inserting
//entries, err := r.get(tx, key)
//if err != nil {
// panic(err) // This should never happen
//}
//if len(entries) > 0 {
// return duplicate, nil
//}
fmt.Println("Key not found. Trying to insert")
// no key exists so insert entry
err = tx.Set(primaryKey(key), []byte(val))
if err != nil {
panic(err) // This should never happen
}
return notDuplicate, tx.Commit()
} This code returns I'll spend some more time and try to figure out why iterator behaves differently. |
Good to know, I have tested out |
I believe this issue meets your Bug Bounty criteria #601 |
The SSI guarantees provided by badger are respected when multiple concurrent transactions try to update the same key at once using the txn.Get and txn.Set API ``` // txn.Get // if not found; txn.Set and Commit ``` but the same guarantees fail when an `iterator` is used instead of the `txn.Get` API ``` // itr.Seek(key) // if not itr.Valid(); txn.Set and Commit ``` If the code above is executed via multiple concurrent transactions, we might overwrite the first update. The test `TestConflict` added in this PR fails on master but works fine on this PR. Fixes #1289
@swdee The issue has been fixed in master. Please try it out and let me know if it fixes your issue. |
The SSI guarantees provided by badger are respected when multiple concurrent transactions try to update the same key at once using the txn.Get and txn.Set API ``` // txn.Get // if not found; txn.Set and Commit ``` but the same guarantees fail when an `iterator` is used instead of the `txn.Get` API ``` // itr.Seek(key) // if not itr.Valid(); txn.Set and Commit ``` If the code above is executed via multiple concurrent transactions, we might overwrite the first update. The test `TestConflict` added in this PR fails on master but works fine on this PR. Fixes #1289
The SSI guarantees provided by badger are respected when multiple concurrent transactions try to update the same key at once using the txn.Get and txn.Set API ``` // txn.Get // if not found; txn.Set and Commit ``` but the same guarantees fail when an `iterator` is used instead of the `txn.Get` API ``` // itr.Seek(key) // if not itr.Valid(); txn.Set and Commit ``` If the code above is executed via multiple concurrent transactions, we might overwrite the first update. The test `TestConflict` added in this PR fails on master but works fine on this PR. Fixes dgraph-io/badger#1289
Go version: 1.13.9
Badger version: 2.0.3
Having used RDBMS for many years I am trying to implement Insert on Duplicate functionality. My first implementation was to create a Badger transaction then check if the key exists and if it doesn't insert the key/value. If the key already exists then the transaction is aborted and a
duplicate
error is returned.The code for this program;
When running this program multiple times, occasionally we get instances where it reports successful insertion multiple times, instead of the expected once.
If we uncomment the two mutex lock lines in the insert() function, this puts a global lock on the Repo which ensures only one entry is inserted. However why does a Badger Transaction not perform as I am expecting with the above use case?
The text was updated successfully, but these errors were encountered: