Open igchor opened 4 years ago
I suggest to expand this API with transactional operations inside lambda expression, and get of not yet committed key:
...
auto *kv = new pmem::kv::db() ;
kv->open("enigne", std::move(cfg));
auto s = kv->transaction([&](pmem:::kv::transaction t) {
t-> put(key, value); //commit when lambda expression ends
kv->get(key); // returns value as is outside transaction
t->get(key); // returns value submitted by transactional put. This may be very useful if you update part of value, and want to abort on some conditions.
}); //commit
@karczex one thing to consider for closure transaction is nesting. For current engines I think we should just allow for single tx per thread but we can relax this in future.
When we have an explicit transaction class I would like to be able to do something like this:
auto tx1 = db.begin_transaction();
tx1.put("k1", "v1"):
auto tx2 = db.begin_transaction();
tx2.put("k2", "v2"):
tx2.commit()
// tx1 is not commited yet, "k1" is not visible
tx1.commit();
For closure-like tx we could either do the same thing (e.g. inner tx is independent) or we flatten the transactions like in C++ (so that, the commit is actually delayed to the outer tx commit). I would prefer the first approach but it will not be consistent with libpmemobj-cpp...
As we talked on the meeting, we can just ban from using nested transactions in case of lambdas. This is probably the simplest approach.
What you should think about is read
or read for write
type operations for transactions. If those aren't possible due to technical reasons, I'm not sure if there's much of a benefit to having transactional API vs a simple batch put.
@pbalcer I was thinking about exposing read/read_for_update via iterators (see read_range in https://github.com/pmem/pmemkv/issues/809). So, there would be no explicit get() method for a transaction but you could mix put's and updates (via iterators) in a single tx. Moreover, with transnational API, we can also mix put's and remove's (we don't have to implement it now, but we can extend that in future).
Anyway, I think the batch_put (in C API at least) would actually look pretty similar. We would have to expose some batch structure (instead of transaction structure) and allow users to call put on that.
FEAT: transactions
Rationale
This is an alternative solution to batch_put: https://github.com/pmem/pmemkv/issues/708 more similar to what RocksDB offers.
Description
The idea is to expose a transaction class which can be used to group puts (and maybe also removes and updates?) into one atomic action.
API Changes
C++
C
Implementation details