transaction_example.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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/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. TransactionDBOptions txn_db_options;
  17. options.create_if_missing = true;
  18. TransactionDB* txn_db;
  19. Status s = TransactionDB::Open(options, txn_db_options, kDBPath, &txn_db);
  20. assert(s.ok());
  21. WriteOptions write_options;
  22. ReadOptions read_options;
  23. TransactionOptions txn_options;
  24. std::string value;
  25. ////////////////////////////////////////////////////////
  26. //
  27. // Simple Transaction Example ("Read Committed")
  28. //
  29. ////////////////////////////////////////////////////////
  30. // Start a transaction
  31. Transaction* txn = txn_db->BeginTransaction(write_options);
  32. assert(txn);
  33. // Read a key in this transaction
  34. s = txn->Get(read_options, "abc", &value);
  35. assert(s.IsNotFound());
  36. // Write a key in this transaction
  37. s = txn->Put("abc", "def");
  38. assert(s.ok());
  39. // Read a key OUTSIDE this transaction. Does not affect txn.
  40. s = txn_db->Get(read_options, "abc", &value);
  41. assert(s.IsNotFound());
  42. // Write a key OUTSIDE of this transaction.
  43. // Does not affect txn since this is an unrelated key.
  44. s = txn_db->Put(write_options, "xyz", "zzz");
  45. assert(s.ok());
  46. // Write a key OUTSIDE of this transaction.
  47. // Fail because the key conflicts with the key written in txn.
  48. s = txn_db->Put(write_options, "abc", "def");
  49. assert(s.subcode() == Status::kLockTimeout);
  50. // Value for key "xyz" has been committed, can be read in txn.
  51. s = txn->Get(read_options, "xyz", &value);
  52. assert(s.ok());
  53. assert(value == "zzz");
  54. // Commit transaction
  55. s = txn->Commit();
  56. assert(s.ok());
  57. delete txn;
  58. // Value is committed, can be read now.
  59. s = txn_db->Get(read_options, "abc", &value);
  60. assert(s.ok());
  61. assert(value == "def");
  62. ////////////////////////////////////////////////////////
  63. //
  64. // "Repeatable Read" (Snapshot Isolation) Example
  65. // -- Using a single Snapshot
  66. //
  67. ////////////////////////////////////////////////////////
  68. // Set a snapshot at start of transaction by setting set_snapshot=true
  69. txn_options.set_snapshot = true;
  70. txn = txn_db->BeginTransaction(write_options, txn_options);
  71. const Snapshot* snapshot = txn->GetSnapshot();
  72. // Write a key OUTSIDE of transaction
  73. s = txn_db->Put(write_options, "abc", "xyz");
  74. assert(s.ok());
  75. // Read the latest committed value.
  76. s = txn->Get(read_options, "abc", &value);
  77. assert(s.ok());
  78. assert(value == "xyz");
  79. // Read the snapshotted value.
  80. read_options.snapshot = snapshot;
  81. s = txn->Get(read_options, "abc", &value);
  82. assert(s.ok());
  83. assert(value == "def");
  84. // Attempt to read a key using the snapshot. This will fail since
  85. // the previous write outside this txn conflicts with this read.
  86. s = txn->GetForUpdate(read_options, "abc", &value);
  87. assert(s.IsBusy());
  88. txn->Rollback();
  89. // Snapshot will be released upon deleting the transaction.
  90. delete txn;
  91. // Clear snapshot from read options since it is no longer valid
  92. read_options.snapshot = nullptr;
  93. snapshot = nullptr;
  94. ////////////////////////////////////////////////////////
  95. //
  96. // "Read Committed" (Monotonic Atomic Views) Example
  97. // --Using multiple Snapshots
  98. //
  99. ////////////////////////////////////////////////////////
  100. // In this example, we set the snapshot multiple times. This is probably
  101. // only necessary if you have very strict isolation requirements to
  102. // implement.
  103. // Set a snapshot at start of transaction
  104. txn_options.set_snapshot = true;
  105. txn = txn_db->BeginTransaction(write_options, txn_options);
  106. // Do some reads and writes to key "x"
  107. read_options.snapshot = txn_db->GetSnapshot();
  108. s = txn->Get(read_options, "x", &value);
  109. assert(s.IsNotFound());
  110. s = txn->Put("x", "x");
  111. assert(s.ok());
  112. // Do a write outside of the transaction to key "y"
  113. s = txn_db->Put(write_options, "y", "y1");
  114. assert(s.ok());
  115. // Set a new snapshot in the transaction
  116. txn->SetSnapshot();
  117. txn->SetSavePoint();
  118. read_options.snapshot = txn_db->GetSnapshot();
  119. // Do some reads and writes to key "y"
  120. // Since the snapshot was advanced, the write done outside of the
  121. // transaction does not conflict.
  122. s = txn->GetForUpdate(read_options, "y", &value);
  123. assert(s.ok());
  124. assert(value == "y1");
  125. s = txn->Put("y", "y2");
  126. assert(s.ok());
  127. // Decide we want to revert the last write from this transaction.
  128. txn->RollbackToSavePoint();
  129. // Commit.
  130. s = txn->Commit();
  131. assert(s.ok());
  132. delete txn;
  133. // Clear snapshot from read options since it is no longer valid
  134. read_options.snapshot = nullptr;
  135. // db state is at the save point.
  136. s = txn_db->Get(read_options, "x", &value);
  137. assert(s.ok());
  138. assert(value == "x");
  139. s = txn_db->Get(read_options, "y", &value);
  140. assert(s.ok());
  141. assert(value == "y1");
  142. // Cleanup
  143. delete txn_db;
  144. DestroyDB(kDBPath, options);
  145. return 0;
  146. }
  147. #endif // ROCKSDB_LITE