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