optimistic_transaction_example.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #ifndef ROCKSDB_LITE
  6. #include "rocksdb/db.h"
  7. #include "rocksdb/options.h"
  8. #include "rocksdb/slice.h"
  9. #include "rocksdb/utilities/transaction.h"
  10. #include "rocksdb/utilities/optimistic_transaction_db.h"
  11. using namespace ROCKSDB_NAMESPACE;
  12. std::string kDBPath = "/tmp/rocksdb_transaction_example";
  13. int main() {
  14. // open DB
  15. Options options;
  16. options.create_if_missing = true;
  17. DB* db;
  18. OptimisticTransactionDB* txn_db;
  19. Status s = OptimisticTransactionDB::Open(options, kDBPath, &txn_db);
  20. assert(s.ok());
  21. db = txn_db->GetBaseDB();
  22. WriteOptions write_options;
  23. ReadOptions read_options;
  24. OptimisticTransactionOptions txn_options;
  25. std::string value;
  26. ////////////////////////////////////////////////////////
  27. //
  28. // Simple OptimisticTransaction Example ("Read Committed")
  29. //
  30. ////////////////////////////////////////////////////////
  31. // Start a transaction
  32. Transaction* txn = txn_db->BeginTransaction(write_options);
  33. assert(txn);
  34. // Read a key in this transaction
  35. s = txn->Get(read_options, "abc", &value);
  36. assert(s.IsNotFound());
  37. // Write a key in this transaction
  38. s = txn->Put("abc", "xyz");
  39. assert(s.ok());
  40. // Read a key OUTSIDE this transaction. Does not affect txn.
  41. s = db->Get(read_options, "abc", &value);
  42. assert(s.IsNotFound());
  43. // Write a key OUTSIDE of this transaction.
  44. // Does not affect txn since this is an unrelated key. If we wrote key 'abc'
  45. // here, the transaction would fail to commit.
  46. s = db->Put(write_options, "xyz", "zzz");
  47. assert(s.ok());
  48. s = db->Put(write_options, "abc", "def");
  49. assert(s.ok());
  50. // Commit transaction
  51. s = txn->Commit();
  52. assert(s.IsBusy());
  53. delete txn;
  54. s = db->Get(read_options, "xyz", &value);
  55. assert(s.ok());
  56. assert(value == "zzz");
  57. s = db->Get(read_options, "abc", &value);
  58. assert(s.ok());
  59. assert(value == "def");
  60. ////////////////////////////////////////////////////////
  61. //
  62. // "Repeatable Read" (Snapshot Isolation) Example
  63. // -- Using a single Snapshot
  64. //
  65. ////////////////////////////////////////////////////////
  66. // Set a snapshot at start of transaction by setting set_snapshot=true
  67. txn_options.set_snapshot = true;
  68. txn = txn_db->BeginTransaction(write_options, txn_options);
  69. const Snapshot* snapshot = txn->GetSnapshot();
  70. // Write a key OUTSIDE of transaction
  71. s = db->Put(write_options, "abc", "xyz");
  72. assert(s.ok());
  73. // Read a key using the snapshot
  74. read_options.snapshot = snapshot;
  75. s = txn->GetForUpdate(read_options, "abc", &value);
  76. assert(s.ok());
  77. assert(value == "def");
  78. // Attempt to commit transaction
  79. s = txn->Commit();
  80. // Transaction could not commit since the write outside of the txn conflicted
  81. // with the read!
  82. assert(s.IsBusy());
  83. delete txn;
  84. // Clear snapshot from read options since it is no longer valid
  85. read_options.snapshot = nullptr;
  86. snapshot = nullptr;
  87. s = db->Get(read_options, "abc", &value);
  88. assert(s.ok());
  89. assert(value == "xyz");
  90. ////////////////////////////////////////////////////////
  91. //
  92. // "Read Committed" (Monotonic Atomic Views) Example
  93. // --Using multiple Snapshots
  94. //
  95. ////////////////////////////////////////////////////////
  96. // In this example, we set the snapshot multiple times. This is probably
  97. // only necessary if you have very strict isolation requirements to
  98. // implement.
  99. // Set a snapshot at start of transaction
  100. txn_options.set_snapshot = true;
  101. txn = txn_db->BeginTransaction(write_options, txn_options);
  102. // Do some reads and writes to key "x"
  103. read_options.snapshot = db->GetSnapshot();
  104. s = txn->Get(read_options, "x", &value);
  105. assert(s.IsNotFound());
  106. s = txn->Put("x", "x");
  107. assert(s.ok());
  108. // The transaction hasn't committed, so the write is not visible
  109. // outside of txn.
  110. s = db->Get(read_options, "x", &value);
  111. assert(s.IsNotFound());
  112. // Do a write outside of the transaction to key "y"
  113. s = db->Put(write_options, "y", "z");
  114. assert(s.ok());
  115. // Set a new snapshot in the transaction
  116. txn->SetSnapshot();
  117. read_options.snapshot = db->GetSnapshot();
  118. // Do some reads and writes to key "y"
  119. s = txn->GetForUpdate(read_options, "y", &value);
  120. assert(s.ok());
  121. assert(value == "z");
  122. txn->Put("y", "y");
  123. // Commit. Since the snapshot was advanced, the write done outside of the
  124. // transaction does not prevent this transaction from Committing.
  125. s = txn->Commit();
  126. assert(s.ok());
  127. delete txn;
  128. // Clear snapshot from read options since it is no longer valid
  129. read_options.snapshot = nullptr;
  130. // txn is committed, read the latest values.
  131. s = db->Get(read_options, "x", &value);
  132. assert(s.ok());
  133. assert(value == "x");
  134. s = db->Get(read_options, "y", &value);
  135. assert(s.ok());
  136. assert(value == "y");
  137. // Cleanup
  138. delete txn_db;
  139. DestroyDB(kDBPath, options);
  140. return 0;
  141. }
  142. #endif // ROCKSDB_LITE