Managing consistency

Batch

A batch enables you to apply multiple write operations at once. With a batch, you can ensure that neither a cursor nor a snapshot can reflect part of the operations of a batch.

Batches are Closeable! You need to either close them after use, or to call use on them.
Using a batch
db.newBatch().use {
    it.delete(oldAddress)
    val addressKey = it.put(newAddress)
    it.put(user.copy(address = addressKey))
    it.write() (1)
}
1 No modification will be applied to the database until write() is called.

If write() is not conditional before closing the batch, you can use execBatch that combines use() and write():

Using and writing a batch
db.execBatch {
    delete(oldAddress)
    val addressKey = put(newAddress)
    put(user.copy(address = addressKey))
}

Snapshot

A snapshot is a read-only version of the database frozen at the time of creation. Write operations that happen after the creation of a snapshot are not reflected to it. Snapshot are most of the times used in conjunction with batches.

Snapshots are Closeable! You need to either close them after use, or to call use on them.
Using a snapshot
val (user, address) = db.newSnapshot().use {
    val user = it[userKey]
    val address = it[user.address]
    user to address
}