Spreads / Spreads.LMDB

Low-level zero-overhead and the fastest LMDB .NET wrapper with some additional native methods useful for Spreads
http://docs.dataspreads.io/spreads/libs/lmdb/api/README.html
Mozilla Public License 2.0
80 stars 9 forks source link

DB creation in/after a transaction #30

Closed chnlkw closed 5 years ago

chnlkw commented 5 years ago

I cannot call env.OpenDatabase() in a created transaction. If I create a db after creating a transaction, db gets null and failed in next operations.

I think new API can be added for this issue: LMDBEnvironment.OpenDatabase(string name, Transaction txn, DatabaseConfig config) or Transaction.OpenDatabase(string name, DatabaseConfig config)

Here is the failed code:

string dir = "spread_lmdb_hello";

if (Directory.Exists(dir))
    Directory.Delete(dir, true);
var env = LMDBEnvironment.Create(dir, LMDBEnvironmentFlags.NoSync | LMDBEnvironmentFlags.WriteMap);
env.Open();

using Transaction txn = env.BeginTransaction();
using var db = env.OpenDatabase("test", new DatabaseConfig(DbFlags.Create)); // db  gets null here.
db.Truncate(txn); // crash with "Spreads.LMDB.LMDBException : Invalid argument"
buybackoff commented 5 years ago

Open a database before any other transaction and never close it. See LMDB docs for mdb_dbi_open. In this lib env.OpenDatabase does not even accepts txn, but internally uses one. If you call it from a different txn it should fail.

buybackoff commented 5 years ago

http://www.lmdb.tech/doc/group__mdb.html#gac08cad5b096925642ca359a6d6f0562a

The database handle will be private to the current transaction until the transaction is successfully committed. If the transaction is aborted the handle will be closed automatically. After a successful commit the handle will reside in the shared environment, and may be used by other transactions.

This function must not be called from multiple concurrent transactions in the same process. A transaction that uses this function must finish (either commit or abort) before any other transaction in the process may use this function.