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