rocksdb/transactions/options.rs
1// Copyright 2021 Yiyuan Liu
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16use crate::ffi;
17
18pub struct TransactionOptions {
19 pub(crate) inner: *mut ffi::rocksdb_transaction_options_t,
20}
21
22unsafe impl Send for TransactionOptions {}
23unsafe impl Sync for TransactionOptions {}
24
25impl Default for TransactionOptions {
26 fn default() -> Self {
27 let txn_opts = unsafe { ffi::rocksdb_transaction_options_create() };
28 assert!(
29 !txn_opts.is_null(),
30 "Could not create RocksDB transaction options"
31 );
32 Self { inner: txn_opts }
33 }
34}
35
36impl TransactionOptions {
37 pub fn new() -> TransactionOptions {
38 TransactionOptions::default()
39 }
40
41 pub fn set_skip_prepare(&mut self, skip_prepare: bool) {
42 unsafe {
43 ffi::rocksdb_transaction_options_set_set_snapshot(self.inner, u8::from(skip_prepare));
44 }
45 }
46
47 /// Specifies use snapshot or not.
48 ///
49 /// Default: false.
50 ///
51 /// If a transaction has a snapshot set, the transaction will ensure that
52 /// any keys successfully written(or fetched via `get_for_update`) have not
53 /// been modified outside this transaction since the time the snapshot was
54 /// set.
55 /// If a snapshot has not been set, the transaction guarantees that keys have
56 /// not been modified since the time each key was first written (or fetched via
57 /// `get_for_update`).
58 ///
59 /// Using snapshot will provide stricter isolation guarantees at the
60 /// expense of potentially more transaction failures due to conflicts with
61 /// other writes.
62 ///
63 /// Calling `set_snapshot` will not affect the version of Data returned by `get`
64 /// methods.
65 pub fn set_snapshot(&mut self, snapshot: bool) {
66 unsafe {
67 ffi::rocksdb_transaction_options_set_set_snapshot(self.inner, u8::from(snapshot));
68 }
69 }
70
71 /// Specifies whether detect deadlock or not.
72 ///
73 /// Setting to true means that before acquiring locks, this transaction will
74 /// check if doing so will cause a deadlock. If so, it will return with
75 /// Status::Busy. The user should retry their transaction.
76 ///
77 /// Default: false.
78 pub fn set_deadlock_detect(&mut self, deadlock_detect: bool) {
79 unsafe {
80 ffi::rocksdb_transaction_options_set_deadlock_detect(
81 self.inner,
82 u8::from(deadlock_detect),
83 );
84 }
85 }
86
87 /// Specifies the wait timeout in milliseconds when a transaction attempts to lock a key.
88 ///
89 /// If 0, no waiting is done if a lock cannot instantly be acquired.
90 /// If negative, transaction lock timeout in `TransactionDBOptions` will be used.
91 ///
92 /// Default: -1.
93 pub fn set_lock_timeout(&mut self, lock_timeout: i64) {
94 unsafe {
95 ffi::rocksdb_transaction_options_set_lock_timeout(self.inner, lock_timeout);
96 }
97 }
98
99 /// Specifies expiration duration in milliseconds.
100 ///
101 /// If non-negative, transactions that last longer than this many milliseconds will fail to commit.
102 /// If not set, a forgotten transaction that is never committed, rolled back, or deleted
103 /// will never relinquish any locks it holds. This could prevent keys from being by other writers.
104 ///
105 /// Default: -1.
106 pub fn set_expiration(&mut self, expiration: i64) {
107 unsafe {
108 ffi::rocksdb_transaction_options_set_expiration(self.inner, expiration);
109 }
110 }
111
112 /// Specifies the number of traversals to make during deadlock detection.
113 ///
114 /// Default: 50.
115 pub fn set_deadlock_detect_depth(&mut self, depth: i64) {
116 unsafe {
117 ffi::rocksdb_transaction_options_set_deadlock_detect_depth(self.inner, depth);
118 }
119 }
120
121 /// Specifies the maximum number of bytes used for the write batch. 0 means no limit.
122 ///
123 /// Default: 0.
124 pub fn set_max_write_batch_size(&mut self, size: usize) {
125 unsafe {
126 ffi::rocksdb_transaction_options_set_max_write_batch_size(self.inner, size);
127 }
128 }
129}
130
131impl Drop for TransactionOptions {
132 fn drop(&mut self) {
133 unsafe {
134 ffi::rocksdb_transaction_options_destroy(self.inner);
135 }
136 }
137}
138
139pub struct TransactionDBOptions {
140 pub(crate) inner: *mut ffi::rocksdb_transactiondb_options_t,
141}
142
143unsafe impl Send for TransactionDBOptions {}
144unsafe impl Sync for TransactionDBOptions {}
145
146impl Default for TransactionDBOptions {
147 fn default() -> Self {
148 let txn_db_opts = unsafe { ffi::rocksdb_transactiondb_options_create() };
149 assert!(
150 !txn_db_opts.is_null(),
151 "Could not create RocksDB transaction_db options"
152 );
153 Self { inner: txn_db_opts }
154 }
155}
156
157impl TransactionDBOptions {
158 pub fn new() -> TransactionDBOptions {
159 TransactionDBOptions::default()
160 }
161
162 /// Specifies the wait timeout in milliseconds when writing a key
163 /// outside a transaction (i.e. by calling `TransactionDB::put` directly).
164 ///
165 /// If 0, no waiting is done if a lock cannot instantly be acquired.
166 /// If negative, there is no timeout and will block indefinitely when acquiring
167 /// a lock.
168 ///
169 /// Not using a timeout can lead to deadlocks. Currently, there
170 /// is no deadlock-detection to recover from a deadlock. While DB writes
171 /// cannot deadlock with other DB writes, they can deadlock with a transaction.
172 /// A negative timeout should only be used if all transactions have a small
173 /// expiration set.
174 ///
175 /// Default: 1000(1s).
176 pub fn set_default_lock_timeout(&mut self, default_lock_timeout: i64) {
177 unsafe {
178 ffi::rocksdb_transactiondb_options_set_default_lock_timeout(
179 self.inner,
180 default_lock_timeout,
181 );
182 }
183 }
184
185 /// Specifies the default wait timeout in milliseconds when a transaction
186 /// attempts to lock a key if not specified in `TransactionOptions`.
187 ///
188 /// If 0, no waiting is done if a lock cannot instantly be acquired.
189 /// If negative, there is no timeout. Not using a timeout is not recommended
190 /// as it can lead to deadlocks. Currently, there is no deadlock-detection to
191 /// recover from a deadlock.
192 ///
193 /// Default: 1000(1s).
194 pub fn set_txn_lock_timeout(&mut self, txn_lock_timeout: i64) {
195 unsafe {
196 ffi::rocksdb_transactiondb_options_set_transaction_lock_timeout(
197 self.inner,
198 txn_lock_timeout,
199 );
200 }
201 }
202
203 /// Specifies the maximum number of keys that can be locked at the same time
204 /// per column family.
205 ///
206 /// If the number of locked keys is greater than `max_num_locks`, transaction
207 /// `writes` (or `get_for_update`) will return an error.
208 /// If this value is not positive, no limit will be enforced.
209 ///
210 /// Default: -1.
211 pub fn set_max_num_locks(&mut self, max_num_locks: i64) {
212 unsafe {
213 ffi::rocksdb_transactiondb_options_set_max_num_locks(self.inner, max_num_locks);
214 }
215 }
216
217 /// Specifies lock table stripes count.
218 ///
219 /// Increasing this value will increase the concurrency by dividing the lock
220 /// table (per column family) into more sub-tables, each with their own
221 /// separate mutex.
222 ///
223 /// Default: 16.
224 pub fn set_num_stripes(&mut self, num_stripes: usize) {
225 unsafe {
226 ffi::rocksdb_transactiondb_options_set_num_stripes(self.inner, num_stripes);
227 }
228 }
229}
230
231impl Drop for TransactionDBOptions {
232 fn drop(&mut self) {
233 unsafe {
234 ffi::rocksdb_transactiondb_options_destroy(self.inner);
235 }
236 }
237}
238
239pub struct OptimisticTransactionOptions {
240 pub(crate) inner: *mut ffi::rocksdb_optimistictransaction_options_t,
241}
242
243unsafe impl Send for OptimisticTransactionOptions {}
244unsafe impl Sync for OptimisticTransactionOptions {}
245
246impl Default for OptimisticTransactionOptions {
247 fn default() -> Self {
248 let txn_opts = unsafe { ffi::rocksdb_optimistictransaction_options_create() };
249 assert!(
250 !txn_opts.is_null(),
251 "Could not create RocksDB optimistic transaction options"
252 );
253 Self { inner: txn_opts }
254 }
255}
256
257impl OptimisticTransactionOptions {
258 pub fn new() -> OptimisticTransactionOptions {
259 OptimisticTransactionOptions::default()
260 }
261
262 /// Specifies use snapshot or not.
263 ///
264 /// Default: false.
265 ///
266 /// If a transaction has a snapshot set, the transaction will ensure that
267 /// any keys successfully written(or fetched via `get_for_update`) have not
268 /// been modified outside the transaction since the time the snapshot was
269 /// set.
270 /// If a snapshot has not been set, the transaction guarantees that keys have
271 /// not been modified since the time each key was first written (or fetched via
272 /// `get_for_update`).
273 ///
274 /// Using snapshot will provide stricter isolation guarantees at the
275 /// expense of potentially more transaction failures due to conflicts with
276 /// other writes.
277 ///
278 /// Calling `set_snapshot` will not affect the version of Data returned by `get`
279 /// methods.
280 pub fn set_snapshot(&mut self, snapshot: bool) {
281 unsafe {
282 ffi::rocksdb_optimistictransaction_options_set_set_snapshot(
283 self.inner,
284 u8::from(snapshot),
285 );
286 }
287 }
288}
289
290impl Drop for OptimisticTransactionOptions {
291 fn drop(&mut self) {
292 unsafe {
293 ffi::rocksdb_optimistictransaction_options_destroy(self.inner);
294 }
295 }
296}