summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authoragiardullo <agiardullo@fb.com>2015-05-29 14:36:35 -0700
committeragiardullo <agiardullo@fb.com>2015-05-29 14:36:35 -0700
commitdc9d70de65d20172147759ee97fd1520b8e2d0eb (patch)
tree456dc77ad4238a7e29ab8e3798678fd1a06b678a /examples
parentd5a0c0e69ba42eafa23de1f19f3d53465b90319f (diff)
Optimistic Transactions
Summary: Optimistic transactions supporting begin/commit/rollback semantics. Currently relies on checking the memtable to determine if there are any collisions at commit time. Not yet implemented would be a way of enuring the memtable has some minimum amount of history so that we won't fail to commit when the memtable is empty. You should probably start with transaction.h to get an overview of what is currently supported. Test Plan: Added a new test, but still need to look into stress testing. Reviewers: yhchiang, igor, rven, sdong Reviewed By: sdong Subscribers: adamretter, MarkCallaghan, leveldb, dhruba Differential Revision: https://reviews.facebook.net/D33435
Diffstat (limited to 'examples')
-rw-r--r--examples/.gitignore1
-rw-r--r--examples/Makefile7
-rw-r--r--examples/transaction_example.cc142
3 files changed, 148 insertions, 2 deletions
diff --git a/examples/.gitignore b/examples/.gitignore
index 5cb04d4b6..7083aa155 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -2,3 +2,4 @@ column_families_example
simple_example
c_simple_example
compact_files_example
+transaction_example
diff --git a/examples/Makefile b/examples/Makefile
index 7bd88fbf0..1535d9b29 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -2,7 +2,7 @@ include ../make_config.mk
.PHONY: clean
-all: simple_example column_families_example compact_files_example c_simple_example
+all: simple_example column_families_example compact_files_example c_simple_example transaction_example
simple_example: simple_example.cc
$(CXX) $(CXXFLAGS) $@.cc -o$@ ../librocksdb.a -I../include -O2 -std=c++11 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) $(EXEC_LDFLAGS)
@@ -19,5 +19,8 @@ compact_files_example: compact_files_example.cc
c_simple_example: c_simple_example.o
$(CXX) $@.o -o$@ ../librocksdb.a $(PLATFORM_LDFLAGS) $(EXEC_LDFLAGS)
+transaction_example: transaction_example.cc
+ $(CXX) $(CXXFLAGS) $@.cc -o$@ ../librocksdb.a -I../include -O2 -std=c++11 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) $(EXEC_LDFLAGS)
+
clean:
- rm -rf ./simple_example ./column_families_example ./compact_files_example ./c_simple_example c_simple_example.o
+ rm -rf ./simple_example ./column_families_example ./compact_files_example ./c_simple_example c_simple_example.o ./transaction_example
diff --git a/examples/transaction_example.cc b/examples/transaction_example.cc
new file mode 100644
index 000000000..02f309c59
--- /dev/null
+++ b/examples/transaction_example.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2015, Facebook, Inc. All rights reserved.
+// This source code is licensed under the BSD-style license found in the
+// LICENSE file in the root directory of this source tree. An additional grant
+// of patent rights can be found in the PATENTS file in the same directory.
+
+#ifndef ROCKSDB_LITE
+
+#include "rocksdb/db.h"
+#include "rocksdb/options.h"
+#include "rocksdb/slice.h"
+#include "rocksdb/utilities/optimistic_transaction.h"
+#include "rocksdb/utilities/optimistic_transaction_db.h"
+
+using namespace rocksdb;
+
+std::string kDBPath = "/tmp/rocksdb_transaction_example";
+
+int main() {
+ // open DB
+ Options options;
+ options.create_if_missing = true;
+ DB* db;
+ OptimisticTransactionDB* txn_db;
+
+ Status s = OptimisticTransactionDB::Open(options, kDBPath, &txn_db);
+ assert(s.ok());
+ db = txn_db->GetBaseDB();
+
+ WriteOptions write_options;
+ ReadOptions read_options;
+ OptimisticTransactionOptions txn_options;
+ std::string value;
+
+ ////////////////////////////////////////////////////////
+ //
+ // Simple OptimisticTransaction Example ("Read Committed")
+ //
+ ////////////////////////////////////////////////////////
+
+ // Start a transaction
+ OptimisticTransaction* txn = txn_db->BeginTransaction(write_options);
+ assert(txn);
+
+ // Read a key in this transaction
+ s = txn->Get(read_options, "abc", &value);
+ assert(s.IsNotFound());
+
+ // Write a key in this transaction
+ txn->Put("abc", "def");
+
+ // Read a key OUTSIDE this transaction. Does not affect txn.
+ s = db->Get(read_options, "abc", &value);
+
+ // Write a key OUTSIDE of this transaction.
+ // Does not affect txn since this is an unrelated key. If we wrote key 'abc'
+ // here, the transaction would fail to commit.
+ s = db->Put(write_options, "xyz", "zzz");
+
+ // Commit transaction
+ s = txn->Commit();
+ assert(s.ok());
+ delete txn;
+
+ ////////////////////////////////////////////////////////
+ //
+ // "Repeatable Read" (Snapshot Isolation) Example
+ // -- Using a single Snapshot
+ //
+ ////////////////////////////////////////////////////////
+
+ // Set a snapshot at start of transaction by setting set_snapshot=true
+ txn_options.set_snapshot = true;
+ txn = txn_db->BeginTransaction(write_options, txn_options);
+
+ const Snapshot* snapshot = txn->GetSnapshot();
+
+ // Write a key OUTSIDE of transaction
+ db->Put(write_options, "abc", "xyz");
+
+ // Read a key using the snapshot
+ read_options.snapshot = snapshot;
+ s = txn->GetForUpdate(read_options, "abc", &value);
+ assert(value == "def");
+
+ // Attempt to commit transaction
+ s = txn->Commit();
+
+ // Transaction could not commit since the write outside of the txn conflicted
+ // with the read!
+ assert(s.IsBusy());
+
+ delete txn;
+ // Clear snapshot from read options since it is no longer valid
+ read_options.snapshot = nullptr;
+ snapshot = nullptr;
+
+ ////////////////////////////////////////////////////////
+ //
+ // "Read Committed" (Monotonic Atomic Views) Example
+ // --Using multiple Snapshots
+ //
+ ////////////////////////////////////////////////////////
+
+ // In this example, we set the snapshot multiple times. This is probably
+ // only necessary if you have very strict isolation requirements to
+ // implement.
+
+ // Set a snapshot at start of transaction
+ txn_options.set_snapshot = true;
+ txn = txn_db->BeginTransaction(write_options, txn_options);
+
+ // Do some reads and writes to key "x"
+ read_options.snapshot = db->GetSnapshot();
+ s = txn->Get(read_options, "x", &value);
+ txn->Put("x", "x");
+
+ // Do a write outside of the transaction to key "y"
+ s = db->Put(write_options, "y", "y");
+
+ // Set a new snapshot in the transaction
+ txn->SetSnapshot();
+ read_options.snapshot = db->GetSnapshot();
+
+ // Do some reads and writes to key "y"
+ s = txn->GetForUpdate(read_options, "y", &value);
+ txn->Put("y", "y");
+
+ // Commit. Since the snapshot was advanced, the write done outside of the
+ // transaction does not prevent this transaction from Committing.
+ s = txn->Commit();
+ assert(s.ok());
+ delete txn;
+ // Clear snapshot from read options since it is no longer valid
+ read_options.snapshot = nullptr;
+
+ // Cleanup
+ delete txn_db;
+ DestroyDB(kDBPath, options);
+ return 0;
+}
+
+#endif // ROCKSDB_LITE