@@ -349,12 +349,19 @@ impl Client {
349349                        err. add_label ( RETRYABLE_WRITE_ERROR ) ; 
350350                    } 
351351
352-                     let  op_retry = match  self . get_op_retryability ( op,  & session)  { 
353-                         Retryability :: Read  => err. is_read_retryable ( ) , 
354-                         Retryability :: Write  => err. is_write_retryable ( ) , 
355-                         _ => false , 
352+                     let  retryability = op. retryability ( ) . with_options ( self . options ( ) ) ; 
353+                     let  can_retry = match  retryability { 
354+                         // Read-retryable operations should be retried on pool cleared errors during 
355+                         // connection checkout regardless of transaction status. 
356+                         Retryability :: Read  if  err. is_pool_cleared ( )  => true , 
357+                         _ => { 
358+                             retryability. can_retry_error ( & err) 
359+                                 && !session
360+                                     . as_ref ( ) 
361+                                     . is_some_and ( |session| session. in_transaction ( ) ) 
362+                         } 
356363                    } ; 
357-                     if  err . is_pool_cleared ( )  || op_retry  { 
364+                     if  can_retry  { 
358365                        retry = Some ( ExecutionRetry  { 
359366                            prior_txn_number :  None , 
360367                            first_error :  err, 
@@ -380,7 +387,7 @@ impl Client {
380387                session = implicit_session. as_mut ( ) ; 
381388            } 
382389
383-             let  retryability = self . get_retryability ( & conn ,   op,  & session) ? ; 
390+             let  retryability = self . get_retryability ( op,  & session,  conn . stream_description ( ) ? ) ; 
384391            if  retryability == Retryability :: None  { 
385392                retry. first_error ( ) ?; 
386393            } 
@@ -449,9 +456,7 @@ impl Client {
449456                        }  else  { 
450457                            return  Err ( r. first_error ) ; 
451458                        } 
452-                     }  else  if  retryability == Retryability :: Read  && err. is_read_retryable ( ) 
453-                         || retryability == Retryability :: Write  && err. is_write_retryable ( ) 
454-                     { 
459+                     }  else  if  retryability. can_retry_error ( & err)  { 
455460                        retry = Some ( ExecutionRetry  { 
456461                            prior_txn_number :  txn_number, 
457462                            first_error :  err, 
@@ -910,52 +915,37 @@ impl Client {
910915        } 
911916    } 
912917
913-     /// Returns the retryability level for the execution of this operation. 
914-      fn  get_op_retryability < T :  Operation > ( 
918+     /// Returns the retryability level for the execution of this operation with the given session 
919+      /// and connection stream description. 
920+      fn  get_retryability < T :  Operation > ( 
915921        & self , 
916922        op :  & T , 
917923        session :  & Option < & mut  ClientSession > , 
924+         stream_description :  & StreamDescription , 
918925    )  -> Retryability  { 
926+         // commitTransaction and abortTransaction are always retried, regardless of the value of 
927+         // retry_writes. 
928+         if  op. name ( )  == CommitTransaction :: NAME  || op. name ( )  == AbortTransaction :: NAME  { 
929+             return  Retryability :: Write ; 
930+         } 
931+ 
919932        if  session
920933            . as_ref ( ) 
921-             . map ( |session| session. in_transaction ( ) ) 
922-             . unwrap_or ( false ) 
934+             . is_some_and ( |session| session. in_transaction ( ) ) 
923935        { 
924936            return  Retryability :: None ; 
925937        } 
926-         match  op. retryability ( )  { 
927-             Retryability :: Read  if  self . inner . options . retry_reads  != Some ( false )  => { 
928-                 Retryability :: Read 
929-             } 
930-             // commitTransaction and abortTransaction should be retried regardless of the 
931-             // value for retry_writes set on the Client 
932-             Retryability :: Write 
933-                 if  op. name ( )  == CommitTransaction :: NAME 
934-                     || op. name ( )  == AbortTransaction :: NAME 
935-                     || self . inner . options . retry_writes  != Some ( false )  =>
936-             { 
938+ 
939+         match  op. retryability ( ) . with_options ( self . options ( ) )  { 
940+             Retryability :: Write  if  stream_description. supports_retryable_writes ( )  => { 
937941                Retryability :: Write 
938942            } 
943+             // All servers compatible with the driver support retryable reads. 
944+             Retryability :: Read  => Retryability :: Read , 
939945            _ => Retryability :: None , 
940946        } 
941947    } 
942948
943-     /// Returns the retryability level for the execution of this operation on this connection. 
944-      fn  get_retryability < T :  Operation > ( 
945-         & self , 
946-         conn :  & PooledConnection , 
947-         op :  & T , 
948-         session :  & Option < & mut  ClientSession > , 
949-     )  -> Result < Retryability >  { 
950-         match  self . get_op_retryability ( op,  session)  { 
951-             Retryability :: Read  => Ok ( Retryability :: Read ) , 
952-             Retryability :: Write  if  conn. stream_description ( ) ?. supports_retryable_writes ( )  => { 
953-                 Ok ( Retryability :: Write ) 
954-             } 
955-             _ => Ok ( Retryability :: None ) , 
956-         } 
957-     } 
958- 
959949    async  fn  update_cluster_time ( 
960950        & self , 
961951        cluster_time :  Option < ClusterTime > , 
0 commit comments