curiosity-ai / rocksdb-sharp

.net bindings for the rocksdb by facebook
BSD 2-Clause "Simplified" License
158 stars 38 forks source link

transactions supported ? #1

Open barry-bvl opened 3 years ago

barry-bvl commented 3 years ago

Just want to check if transactions in RocksDb are supported by the C# library? I saw it was possible in the c++ API but I did not see it immediately in the C# library but maybe I overlooked something.

The only way I think I could do it is using the low level bindings.

something like the following (just some hack example)

public static void TryTranscation() { IntPtr options = Native.Instance.rocksdb_options_create(); Native.Instance.rocksdb_options_set_create_if_missing(options,true); IntPtr transactionDbOptions = Native.Instance.rocksdb_transactiondb_options_create(); var txDb = Native.Instance.rocksdb_transactiondb_open(options,transactionDbOptions,(IntPtr)Marshal.StringToHGlobalAnsi("F:\tryout\rocksdb"),out IntPtr error); Debug.Assert(error == IntPtr.Zero);

        IntPtr writeOptions = Native.Instance.rocksdb_writeoptions_create();
        IntPtr transactionOptions = Native.Instance.rocksdb_transaction_options_create();
        var tx = Native.Instance.rocksdb_transaction_begin(txDb, writeOptions, transactionOptions, IntPtr.Zero);

        //put value in transaction
        Native.Instance.rocksdb_transaction_put(tx,
                                                Encoding.Unicode.GetBytes($"mykey"),
                                                new UIntPtr((uint)Encoding.Unicode.GetBytes($"mykey").Length),
                                                Encoding.Unicode.GetBytes($"myvalue"),
                                                new UIntPtr((uint)Encoding.Unicode.GetBytes($"myvalue").Length));

        //retrieve value (tx not yet commmited so should not found something)
        IntPtr readOptions = Native.Instance.rocksdb_readoptions_create();
        var valduringTX = Native.Instance.rocksdb_transactiondb_get(txDb, readOptions, Encoding.Unicode.GetBytes($"mykey"), new UIntPtr((uint)Encoding.Unicode.GetBytes($"mykey").Length), out UIntPtr vLength);
        if(valduringTX == IntPtr.Zero)
        {
            Console.WriteLine($"Value not found");
        }
        else
        {
            byte[] valresult = new byte[vLength.ToUInt64()];
            Marshal.Copy(valduringTX, valresult, (int)0, (int)vLength);
            Native.Instance.rocksdb_free(valduringTX);
        }

        Native.Instance.rocksdb_transaction_commit(tx, out IntPtr commitError);
        Debug.Assert(commitError == IntPtr.Zero);

        //retrieve value
        //IntPtr readOptions = Native.Instance.rocksdb_readoptions_create();
        var val = Native.Instance.rocksdb_transactiondb_get(txDb,readOptions,Encoding.Unicode.GetBytes($"mykey"),new UIntPtr((uint)Encoding.Unicode.GetBytes($"mykey").Length),out vLength);
        byte[] result = new byte[vLength.ToUInt64()];
        Marshal.Copy(val, result, (int)0, (int)vLength);
        Native.Instance.rocksdb_free(val);
        Console.WriteLine($"value found: {Encoding.Unicode.GetString(result)}"  );

        //cleanup
        Native.Instance.rocksdb_transactiondb_close(txDb);
        Native.Instance.rocksdb_writeoptions_destroy(writeOptions);
        Native.Instance.rocksdb_options_destroy(options);
        Native.Instance.rocksdb_readoptions_destroy(readOptions);
        Native.Instance.rocksdb_transaction_options_destroy(transactionOptions);
        Native.Instance.rocksdb_transactiondb_options_destroy(transactionDbOptions);

    }
theolivenbaum commented 3 years ago

Hi @barry-bvl,

As far as I know, you can do transactions with the batch mode:

using var batch = new WriteBatch();
batch.Put(key1, bytes1, myDbFamily1);
batch.Put(key2, bytes2, myDbFamily2);
batch.Put(key3, bytes3, myDbFamily3);
DB.Write(batch);

Is this the use-case you had in mind?

barry-bvl commented 3 years ago

Thx for the reply but I was looking for something more then the writebatch (which I was aware that this was available, and this gives you under the hood in deed some kind of atomicity/transaction). But I would rather be able to to use for instance concepts like OptimisticTransactionDB which would not require locking of the keys

theolivenbaum commented 3 years ago

Ah I missed the part where you're also reading in the code - then yes WriteBatch won't do it... If you want to extend the current C# API with support for this, happy to incorporate the changes in a PR

DejanPelzel commented 1 year ago

I've added basic transaction support in a PR just now, hopefully we can get this built in :)

riemannulus commented 2 weeks ago

Do you have any updates? It seems that #47 implemented this issue, but any comment is not in there. Is there any problem with hanging PR?