# Keeping key version when adding same key on the same transaction

**URL:** <https://discuss.dgraph.io/t/keeping-key-version-when-adding-same-key-on-the-same-transaction/10501>\
**Category:** Badger\
**Tags:** kind:question\
**Created:** [September 21, 2020, 2:50pm UTC](https://discuss.dgraph.io/t/keeping-key-version-when-adding-same-key-on-the-same-transaction/10501 "2020-09-21T14:50:27Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![sezaru](https://avatars.discourse-cdn.com/v4/letter/s/0ea827/32.png) [@sezaru](https://discuss.dgraph.io/u/sezaru)\
**Post date:** [September 21, 2020, 2:50pm UTC](https://discuss.dgraph.io/t/keeping-key-version-when-adding-same-key-on-the-same-transaction/10501/1 "2020-09-21T14:50:27Z")

</div>

Is it possible to keep the key version when adding the same key from the same transaction (or write batch)?

For example:

If I add a key `a` in the same transaction twice, only the last one is commited:

```auto
txn := db.NewTransaction(true)
defer txn.Discard()

err = txn.Set([]byte("a"), []byte("41"))
if err != nil {
	log.Fatal(err)
}

err = txn.Set([]byte("a"), []byte("42"))
if err != nil {
	log.Fatal(err)
}

if err := txn.Commit(); err != nil {
	log.Fatal(err)
}

```

This will return only `42` when I iterate through key `a`.

But, if I split the transaction into 2 transactions:

```auto
{
	txn := db.NewTransaction(true)
	defer txn.Discard()

	err = txn.Set([]byte("a"), []byte("41"))
	if err != nil {
		log.Fatal(err)
	}

	if err := txn.Commit(); err != nil {
		log.Fatal(err)
	}
}

{
	txn := db.NewTransaction(true)
	defer txn.Discard()

	err = txn.Set([]byte("a"), []byte("42"))
	if err != nil {
		log.Fatal(err)
	}

	if err := txn.Commit(); err != nil {
		log.Fatal(err)
	}
}

```

Now I get the desired `41` and `42` values during iteration.

My reason to want that is that my `WriteBatch` is created from another system, and it is possible that a repeated key is inside that batch.

Best regards,

Eduardo

---

<div class="post-metadata">

**Author:** ![sezaru](https://avatars.discourse-cdn.com/v4/letter/s/0ea827/32.png) [@sezaru](https://discuss.dgraph.io/u/sezaru)\
**Post date:** [September 21, 2020, 3:39pm UTC](https://discuss.dgraph.io/t/keeping-key-version-when-adding-same-key-on-the-same-transaction/10501/2 "2020-09-21T15:39:26Z")

</div>

I think I found out a way to do this, if I open the database as a managed DB, I can specify the version timestamp for each key and then my values will be added correctly.

The only issue now is that with this approach, seems like `NumVersionsToKeep` is ignored, since I always get all versions for that key during iteration instead of only the max number by above option.

This is the code:

```auto
options := badger.DefaultOptions("./badger_db").WithNumVersionsToKeep(2)

db, err := badger.OpenManaged(options)
if err != nil {
	log.Fatal(err)
}
defer db.Close()

batch := db.NewManagedWriteBatch()
defer batch.Cancel()

err = batch.SetEntryAt(&badger.Entry{Key: []byte("a"), Value: []byte("41")}, uint64(time.Now().UnixNano()))
if err != nil {
	log.Fatal(err)
}

err = batch.SetEntryAt(&badger.Entry{Key: []byte("a"), Value: []byte("42")}, uint64(time.Now().UnixNano()))
if err != nil {
	log.Fatal(err)
}

err = batch.Flush()
if err != nil {
	log.Fatal(err)
}

```

---

<div class="post-metadata">

**Author:** ![sezaru](https://avatars.discourse-cdn.com/v4/letter/s/0ea827/32.png) [@sezaru](https://discuss.dgraph.io/u/sezaru)\
**Post date:** [September 23, 2020, 10:52pm UTC](https://discuss.dgraph.io/t/keeping-key-version-when-adding-same-key-on-the-same-transaction/10501/3 "2020-09-23T22:52:12Z")

</div>

Hmm… No one knows how to fix this? There is not much documentation about ManagedDB

---

<div class="post-metadata">

**Author:** ![ibrahim](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/ibrahim/32/6387_2.png) [@ibrahim](https://discuss.dgraph.io/u/ibrahim)\
**Post date:** [September 24, 2020, 6:44am UTC](https://discuss.dgraph.io/t/keeping-key-version-when-adding-same-key-on-the-same-transaction/10501/4 "2020-09-24T06:44:46Z")

</div>

Hey @sezaru, apologies for the delay in the reply.  
Badger keeps the transactions in-memory before they’re committed.

> <https://github.com/dgraph-io/badger/blob/c701ecabd26592449be5df11e6b76ffbe298c37a/txn.go#L261>

In normal mode, if you write the same key twice, we will overwrite the first value (which is fine because you want to update the value).

You’re correct that you will need managed mode. The `setEntryAt` will commit entry at a specific timestamp. However, please be aware that managed mode is used when the application can deal with transaction conflicts and provide correct timestamps (dgraph used managed mode and deals with this).

If you commit things at an incorrect timestamp, you might not be able to read it correctly.

> [@sezaru](#):
>
> The only issue now is that with this approach, seems like `NumVersionsToKeep` is ignored, since I always get all versions for that key during iteration instead of only the max number by above option.

The `NumVersionsToKeep` flag is not used in the iterators. The `NumVersionsToKeep` flag is used by compaction to determine if the value should be kept or removed. So if the data you inserted is compacted (which happens when you have enough data), we will remove more than 2 versions of the key.  
Iterators do not respect the `NumVersionsToKeep` flag.
