Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transactions supported ? #1

Open
barry-bvl opened this issue Sep 30, 2020 · 5 comments
Open

transactions supported ? #1

barry-bvl opened this issue Sep 30, 2020 · 5 comments

Comments

@barry-bvl
Copy link

barry-bvl commented Sep 30, 2020

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
Copy link
Contributor

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
Copy link
Author

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
Copy link
Contributor

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
Copy link

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

@riemannulus
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants