@@ -116,6 +116,17 @@ impl<PdC: PdClient> Transaction<PdC> {
116
116
}
117
117
118
118
/// Create a `get for udpate` request.
119
+ /// It has different behaviors in optimistic and pessimistic transactions.
120
+ ///
121
+ /// # Optimistic transaction
122
+ /// Once resolved this request will retrieve the value just like a normal `get` request,
123
+ /// and "locks" the key. This lock will not affect other (concurrent) transactions, but will
124
+ /// prevent the current transaction from successfully committing if there is another write
125
+ /// containing the "locked" key which is committed between the start and commit of the current transaction.
126
+ ///
127
+ /// The value is read from the `start timestamp`, thus it is cached in the local buffer.
128
+ ///
129
+ /// # Pessimistic transaction
119
130
/// Once resolved this request will pessimistically lock and fetch the latest
120
131
/// value associated with the given key at **current timestamp**.
121
132
///
@@ -127,8 +138,6 @@ impl<PdC: PdClient> Transaction<PdC> {
127
138
/// So normal `get`-like commands after `get_for_update` will not be influenced, they still read values at `start_ts`.
128
139
///
129
140
///
130
- /// It can only be used in pessimistic mode.
131
- ///
132
141
/// # Examples
133
142
/// ```rust,no_run
134
143
/// # use tikv_client::{Value, Config, TransactionClient};
@@ -146,7 +155,9 @@ impl<PdC: PdClient> Transaction<PdC> {
146
155
pub async fn get_for_update ( & mut self , key : impl Into < Key > ) -> Result < Option < Value > > {
147
156
self . check_allow_operation ( ) . await ?;
148
157
if !self . is_pessimistic ( ) {
149
- Err ( Error :: InvalidTransactionType )
158
+ let key = key. into ( ) ;
159
+ self . lock_keys ( iter:: once ( key. clone ( ) ) ) . await ?;
160
+ self . get ( key) . await
150
161
} else {
151
162
let mut pairs = self . pessimistic_lock ( iter:: once ( key. into ( ) ) , true ) . await ?;
152
163
debug_assert ! ( pairs. len( ) <= 1 ) ;
@@ -227,7 +238,17 @@ impl<PdC: PdClient> Transaction<PdC> {
227
238
}
228
239
229
240
/// Create a new 'batch get for update' request.
241
+ /// It has different behaviors in optimistic and pessimistic transactions.
230
242
///
243
+ /// # Optimistic transaction
244
+ /// Once resolved this request will retrieve the values just like a normal `batch_get` request,
245
+ /// and "locks" the keys. The locks will not affect other (concurrent) transactions, but will
246
+ /// prevent the current transaction from successfully committing if there is any other write
247
+ /// containing a "locked" key which is committed between the start and commit of the current transaction.
248
+ ///
249
+ /// The values are read from the `start timestamp`, thus they are cached in the local buffer.
250
+ ///
251
+ /// # Pessimistic transaction
231
252
/// Once resolved this request will pessimistically lock the keys and
232
253
/// fetch the values associated with the given keys.
233
254
///
@@ -238,23 +259,20 @@ impl<PdC: PdClient> Transaction<PdC> {
238
259
///
239
260
/// Non-existent entries will not appear in the result. The order of the keys is not retained in the result.
240
261
///
241
- /// It can only be used in pessimistic mode.
242
262
///
243
263
/// # Examples
244
264
/// ```rust,no_run
245
- /// # use tikv_client::{Key, Value, Config, TransactionClient};
265
+ /// # use tikv_client::{Key, Value, Config, TransactionClient, KvPair };
246
266
/// # use futures::prelude::*;
247
267
/// # use std::collections::HashMap;
248
268
/// # futures::executor::block_on(async {
249
269
/// # let client = TransactionClient::new(vec!["192.168.0.100", "192.168.0.101"]).await.unwrap();
250
270
/// let mut txn = client.begin_pessimistic().await.unwrap();
251
271
/// let keys = vec!["TiKV".to_owned(), "TiDB".to_owned()];
252
- /// let result: HashMap<Key, Value > = txn
272
+ /// let result: Vec<KvPair > = txn
253
273
/// .batch_get_for_update(keys)
254
274
/// .await
255
- /// .unwrap()
256
- /// .map(|pair| (pair.0, pair.1))
257
- /// .collect();
275
+ /// .unwrap();
258
276
/// // now "TiKV" and "TiDB" are both locked
259
277
/// // Finish the transaction...
260
278
/// txn.commit().await.unwrap();
@@ -263,13 +281,15 @@ impl<PdC: PdClient> Transaction<PdC> {
263
281
pub async fn batch_get_for_update (
264
282
& mut self ,
265
283
keys : impl IntoIterator < Item = impl Into < Key > > ,
266
- ) -> Result < impl Iterator < Item = KvPair > > {
284
+ ) -> Result < Vec < KvPair > > {
267
285
self . check_allow_operation ( ) . await ?;
286
+ let keys: Vec < Key > = keys. into_iter ( ) . map ( |k| k. into ( ) ) . collect ( ) ;
268
287
if !self . is_pessimistic ( ) {
269
- return Err ( Error :: InvalidTransactionType ) ;
288
+ self . lock_keys ( keys. clone ( ) ) . await ?;
289
+ Ok ( self . batch_get ( keys) . await ?. collect ( ) )
290
+ } else {
291
+ self . pessimistic_lock ( keys, true ) . await
270
292
}
271
- let keys: Vec < Key > = keys. into_iter ( ) . map ( |it| it. into ( ) ) . collect ( ) ;
272
- Ok ( self . pessimistic_lock ( keys, true ) . await ?. into_iter ( ) )
273
293
}
274
294
275
295
/// Create a new 'scan' request.
@@ -470,8 +490,8 @@ impl<PdC: PdClient> Transaction<PdC> {
470
490
}
471
491
}
472
492
TransactionKind :: Pessimistic ( _) => {
473
- self . pessimistic_lock ( keys. into_iter ( ) . map ( |k| k. into ( ) ) , false )
474
- . await ?;
493
+ let keys: Vec < Key > = keys . into_iter ( ) . map ( |k| k. into ( ) ) . collect ( ) ;
494
+ self . pessimistic_lock ( keys . into_iter ( ) , false ) . await ?;
475
495
}
476
496
}
477
497
Ok ( ( ) )
0 commit comments