transaction_example.cc 5.6 KB

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