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).
8 import static java
.nio
.charset
.StandardCharsets
.UTF_8
;
11 * Demonstrates using Transactions on an OptimisticTransactionDB with
12 * varying isolation guarantees
14 public class OptimisticTransactionSample
{
15 private static final String dbPath
= "/tmp/rocksdb_optimistic_transaction_example";
17 public static final void main(final String args
[]) throws RocksDBException
{
19 try(final Options options
= new Options()
20 .setCreateIfMissing(true);
21 final OptimisticTransactionDB txnDb
=
22 OptimisticTransactionDB
.open(options
, dbPath
)) {
24 try (final WriteOptions writeOptions
= new WriteOptions();
25 final ReadOptions readOptions
= new ReadOptions()) {
27 ////////////////////////////////////////////////////////
29 // Simple OptimisticTransaction Example ("Read Committed")
31 ////////////////////////////////////////////////////////
32 readCommitted(txnDb
, writeOptions
, readOptions
);
35 ////////////////////////////////////////////////////////
37 // "Repeatable Read" (Snapshot Isolation) Example
38 // -- Using a single Snapshot
40 ////////////////////////////////////////////////////////
41 repeatableRead(txnDb
, writeOptions
, readOptions
);
44 ////////////////////////////////////////////////////////
46 // "Read Committed" (Monotonic Atomic Views) Example
47 // --Using multiple Snapshots
49 ////////////////////////////////////////////////////////
50 readCommitted_monotonicAtomicViews(txnDb
, writeOptions
, readOptions
);
56 * Demonstrates "Read Committed" isolation
58 private static void readCommitted(final OptimisticTransactionDB txnDb
,
59 final WriteOptions writeOptions
, final ReadOptions readOptions
)
60 throws RocksDBException
{
61 final byte key1
[] = "abc".getBytes(UTF_8
);
62 final byte value1
[] = "def".getBytes(UTF_8
);
64 final byte key2
[] = "xyz".getBytes(UTF_8
);
65 final byte value2
[] = "zzz".getBytes(UTF_8
);
67 // Start a transaction
68 try(final Transaction txn
= txnDb
.beginTransaction(writeOptions
)) {
69 // Read a key in this transaction
70 byte[] value
= txn
.get(readOptions
, key1
);
71 assert(value
== null);
73 // Write a key in this transaction
74 txn
.put(key1
, value1
);
76 // Read a key OUTSIDE this transaction. Does not affect txn.
77 value
= txnDb
.get(readOptions
, key1
);
78 assert(value
== null);
80 // Write a key OUTSIDE of this transaction.
81 // Does not affect txn since this is an unrelated key.
82 // If we wrote key 'abc' here, the transaction would fail to commit.
83 txnDb
.put(writeOptions
, key2
, value2
);
91 * Demonstrates "Repeatable Read" (Snapshot Isolation) isolation
93 private static void repeatableRead(final OptimisticTransactionDB txnDb
,
94 final WriteOptions writeOptions
, final ReadOptions readOptions
)
95 throws RocksDBException
{
97 final byte key1
[] = "ghi".getBytes(UTF_8
);
98 final byte value1
[] = "jkl".getBytes(UTF_8
);
100 // Set a snapshot at start of transaction by setting setSnapshot(true)
101 try(final OptimisticTransactionOptions txnOptions
=
102 new OptimisticTransactionOptions().setSetSnapshot(true);
103 final Transaction txn
=
104 txnDb
.beginTransaction(writeOptions
, txnOptions
)) {
106 final Snapshot snapshot
= txn
.getSnapshot();
108 // Write a key OUTSIDE of transaction
109 txnDb
.put(writeOptions
, key1
, value1
);
111 // Read a key using the snapshot.
112 readOptions
.setSnapshot(snapshot
);
113 final byte[] value
= txn
.getForUpdate(readOptions
, key1
, true);
114 assert(value
== value1
);
117 // Attempt to commit transaction
119 throw new IllegalStateException();
120 } catch(final RocksDBException e
) {
121 // Transaction could not commit since the write outside of the txn
122 // conflicted with the read!
123 assert(e
.getStatus().getCode() == Status
.Code
.Busy
);
128 // Clear snapshot from read options since it is no longer valid
129 readOptions
.setSnapshot(null);
134 * Demonstrates "Read Committed" (Monotonic Atomic Views) isolation
136 * In this example, we set the snapshot multiple times. This is probably
137 * only necessary if you have very strict isolation requirements to
140 private static void readCommitted_monotonicAtomicViews(
141 final OptimisticTransactionDB txnDb
, final WriteOptions writeOptions
,
142 final ReadOptions readOptions
) throws RocksDBException
{
144 final byte keyX
[] = "x".getBytes(UTF_8
);
145 final byte valueX
[] = "x".getBytes(UTF_8
);
147 final byte keyY
[] = "y".getBytes(UTF_8
);
148 final byte valueY
[] = "y".getBytes(UTF_8
);
150 try (final OptimisticTransactionOptions txnOptions
=
151 new OptimisticTransactionOptions().setSetSnapshot(true);
152 final Transaction txn
=
153 txnDb
.beginTransaction(writeOptions
, txnOptions
)) {
155 // Do some reads and writes to key "x"
156 Snapshot snapshot
= txnDb
.getSnapshot();
157 readOptions
.setSnapshot(snapshot
);
158 byte[] value
= txn
.get(readOptions
, keyX
);
159 txn
.put(valueX
, valueX
);
161 // Do a write outside of the transaction to key "y"
162 txnDb
.put(writeOptions
, keyY
, valueY
);
164 // Set a new snapshot in the transaction
166 snapshot
= txnDb
.getSnapshot();
167 readOptions
.setSnapshot(snapshot
);
169 // Do some reads and writes to key "y"
170 // Since the snapshot was advanced, the write done outside of the
171 // transaction does not conflict.
172 value
= txn
.getForUpdate(readOptions
, keyY
, true);
173 txn
.put(keyY
, valueY
);
175 // Commit. Since the snapshot was advanced, the write done outside of the
176 // transaction does not prevent this transaction from Committing.
180 // Clear snapshot from read options since it is no longer valid
181 readOptions
.setSnapshot(null);