@@ -113,7 +113,7 @@ impl<PdC: PdClient> Transaction<PdC> {
113113 /// ```
114114 pub async fn get ( & mut self , key : impl Into < Key > ) -> Result < Option < Value > > {
115115 debug ! ( self . logger, "invoking transactional get request" ) ;
116- self . check_allow_operation ( ) . await ?;
116+ self . check_allow_operation ( true ) . await ?;
117117 let timestamp = self . timestamp . clone ( ) ;
118118 let rpc = self . rpc . clone ( ) ;
119119 let key = key. into ( ) ;
@@ -177,7 +177,7 @@ impl<PdC: PdClient> Transaction<PdC> {
177177 /// ```
178178 pub async fn get_for_update ( & mut self , key : impl Into < Key > ) -> Result < Option < Value > > {
179179 debug ! ( self . logger, "invoking transactional get_for_update request" ) ;
180- self . check_allow_operation ( ) . await ?;
180+ self . check_allow_operation ( false ) . await ?;
181181 if !self . is_pessimistic ( ) {
182182 let key = key. into ( ) ;
183183 self . lock_keys ( iter:: once ( key. clone ( ) ) ) . await ?;
@@ -244,7 +244,7 @@ impl<PdC: PdClient> Transaction<PdC> {
244244 keys : impl IntoIterator < Item = impl Into < Key > > ,
245245 ) -> Result < impl Iterator < Item = KvPair > > {
246246 debug ! ( self . logger, "invoking transactional batch_get request" ) ;
247- self . check_allow_operation ( ) . await ?;
247+ self . check_allow_operation ( true ) . await ?;
248248 let timestamp = self . timestamp . clone ( ) ;
249249 let rpc = self . rpc . clone ( ) ;
250250 let retry_options = self . options . retry_options . clone ( ) ;
@@ -299,7 +299,7 @@ impl<PdC: PdClient> Transaction<PdC> {
299299 self . logger,
300300 "invoking transactional batch_get_for_update request"
301301 ) ;
302- self . check_allow_operation ( ) . await ?;
302+ self . check_allow_operation ( false ) . await ?;
303303 let keys: Vec < Key > = keys. into_iter ( ) . map ( |k| k. into ( ) ) . collect ( ) ;
304304 if !self . is_pessimistic ( ) {
305305 self . lock_keys ( keys. clone ( ) ) . await ?;
@@ -433,7 +433,7 @@ impl<PdC: PdClient> Transaction<PdC> {
433433 /// ```
434434 pub async fn put ( & mut self , key : impl Into < Key > , value : impl Into < Value > ) -> Result < ( ) > {
435435 debug ! ( self . logger, "invoking transactional put request" ) ;
436- self . check_allow_operation ( ) . await ?;
436+ self . check_allow_operation ( false ) . await ?;
437437 let key = key. into ( ) ;
438438 if self . is_pessimistic ( ) {
439439 self . pessimistic_lock ( iter:: once ( key. clone ( ) ) , false )
@@ -464,7 +464,7 @@ impl<PdC: PdClient> Transaction<PdC> {
464464 /// ```
465465 pub async fn insert ( & mut self , key : impl Into < Key > , value : impl Into < Value > ) -> Result < ( ) > {
466466 debug ! ( self . logger, "invoking transactional insert request" ) ;
467- self . check_allow_operation ( ) . await ?;
467+ self . check_allow_operation ( false ) . await ?;
468468 let key = key. into ( ) ;
469469 if self . buffer . get ( & key) . is_some ( ) {
470470 return Err ( Error :: DuplicateKeyInsertion ) ;
@@ -499,7 +499,7 @@ impl<PdC: PdClient> Transaction<PdC> {
499499 /// ```
500500 pub async fn delete ( & mut self , key : impl Into < Key > ) -> Result < ( ) > {
501501 debug ! ( self . logger, "invoking transactional delete request" ) ;
502- self . check_allow_operation ( ) . await ?;
502+ self . check_allow_operation ( false ) . await ?;
503503 let key = key. into ( ) ;
504504 if self . is_pessimistic ( ) {
505505 self . pessimistic_lock ( iter:: once ( key. clone ( ) ) , false )
@@ -537,7 +537,7 @@ impl<PdC: PdClient> Transaction<PdC> {
537537 keys : impl IntoIterator < Item = impl Into < Key > > ,
538538 ) -> Result < ( ) > {
539539 debug ! ( self . logger, "invoking transactional lock_keys request" ) ;
540- self . check_allow_operation ( ) . await ?;
540+ self . check_allow_operation ( false ) . await ?;
541541 match self . options . kind {
542542 TransactionKind :: Optimistic => {
543543 for key in keys {
@@ -569,6 +569,15 @@ impl<PdC: PdClient> Transaction<PdC> {
569569 /// ```
570570 pub async fn commit ( & mut self ) -> Result < Option < Timestamp > > {
571571 debug ! ( self . logger, "commiting transaction" ) ;
572+
573+ {
574+ // readonly transaction no need to commit
575+ let status = self . status . read ( ) . await ;
576+ if * status == TransactionStatus :: ReadOnly {
577+ return Ok ( None ) ;
578+ }
579+ }
580+
572581 {
573582 let mut status = self . status . write ( ) . await ;
574583 if !matches ! (
@@ -677,7 +686,7 @@ impl<PdC: PdClient> Transaction<PdC> {
677686 #[ doc( hidden) ]
678687 pub async fn send_heart_beat ( & mut self ) -> Result < u64 > {
679688 debug ! ( self . logger, "sending heart_beat" ) ;
680- self . check_allow_operation ( ) . await ?;
689+ self . check_allow_operation ( true ) . await ?;
681690 let primary_key = match self . buffer . get_primary_key ( ) {
682691 Some ( k) => k,
683692 None => return Err ( Error :: NoPrimaryKey ) ,
@@ -703,7 +712,7 @@ impl<PdC: PdClient> Transaction<PdC> {
703712 key_only : bool ,
704713 reverse : bool ,
705714 ) -> Result < impl Iterator < Item = KvPair > > {
706- self . check_allow_operation ( ) . await ?;
715+ self . check_allow_operation ( true ) . await ?;
707716 let timestamp = self . timestamp . clone ( ) ;
708717 let rpc = self . rpc . clone ( ) ;
709718 let retry_options = self . options . retry_options . clone ( ) ;
@@ -840,10 +849,17 @@ impl<PdC: PdClient> Transaction<PdC> {
840849 }
841850
842851 /// Checks if the transaction can perform arbitrary operations.
843- async fn check_allow_operation ( & self ) -> Result < ( ) > {
852+ async fn check_allow_operation ( & self , readonly : bool ) -> Result < ( ) > {
844853 let status = self . status . read ( ) . await ;
845854 match * status {
846- TransactionStatus :: ReadOnly | TransactionStatus :: Active => Ok ( ( ) ) ,
855+ TransactionStatus :: Active => Ok ( ( ) ) ,
856+ TransactionStatus :: ReadOnly => {
857+ if readonly {
858+ Ok ( ( ) )
859+ } else {
860+ Err ( Error :: OperationReadOnlyError )
861+ }
862+ }
847863 TransactionStatus :: Committed
848864 | TransactionStatus :: Rolledback
849865 | TransactionStatus :: StartedCommit
0 commit comments