@@ -2010,6 +2010,7 @@ async def _retry_internal(
20102010 retryable : bool = False ,
20112011 operation_id : Optional [int ] = None ,
20122012 is_run_command : bool = False ,
2013+ is_aggregate_write : bool = False ,
20132014 ) -> T :
20142015 """Internal retryable helper for all client transactions.
20152016
@@ -2022,6 +2023,7 @@ async def _retry_internal(
20222023 :param read_pref: Topology of read operation, defaults to None
20232024 :param retryable: If the operation should be retried once, defaults to None
20242025 :param is_run_command: If this is a runCommand operation, defaults to False
2026+ :param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
20252027
20262028 :return: Output of the calling func()
20272029 """
@@ -2037,6 +2039,7 @@ async def _retry_internal(
20372039 retryable = retryable ,
20382040 operation_id = operation_id ,
20392041 is_run_command = is_run_command ,
2042+ is_aggregate_write = is_aggregate_write ,
20402043 ).run ()
20412044
20422045 async def _retryable_read (
@@ -2049,6 +2052,7 @@ async def _retryable_read(
20492052 retryable : bool = True ,
20502053 operation_id : Optional [int ] = None ,
20512054 is_run_command : bool = False ,
2055+ is_aggregate_write : bool = False ,
20522056 ) -> T :
20532057 """Execute an operation with consecutive retries if possible
20542058
@@ -2065,6 +2069,7 @@ async def _retryable_read(
20652069 :param retryable: if we should attempt retries
20662070 (may not always be supported even if supplied), defaults to False
20672071 :param is_run_command: If this is a runCommand operation, defaults to False.
2072+ :param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
20682073 """
20692074
20702075 # Ensure that the client supports retrying on reads and there is no session in
@@ -2084,6 +2089,7 @@ async def _retryable_read(
20842089 retryable = retryable ,
20852090 operation_id = operation_id ,
20862091 is_run_command = is_run_command ,
2092+ is_aggregate_write = is_aggregate_write ,
20872093 )
20882094
20892095 async def _retryable_write (
@@ -2754,6 +2760,7 @@ def __init__(
27542760 retryable : bool = False ,
27552761 operation_id : Optional [int ] = None ,
27562762 is_run_command : bool = False ,
2763+ is_aggregate_write : bool = False ,
27572764 ):
27582765 self ._last_error : Optional [Exception ] = None
27592766 self ._retrying = False
@@ -2777,6 +2784,7 @@ def __init__(
27772784 self ._operation_id = operation_id
27782785 self ._attempt_number = 0
27792786 self ._is_run_command = is_run_command
2787+ self ._is_aggregate_write = is_aggregate_write
27802788
27812789 async def run (self ) -> T :
27822790 """Runs the supplied func() and attempts a retry
@@ -2822,6 +2830,9 @@ async def run(self) -> T:
28222830 self ._client .options .retry_reads and self ._client .options .retry_writes
28232831 ):
28242832 raise
2833+ if self ._is_aggregate_write and not self ._client .options .retry_writes :
2834+ raise
2835+
28252836 # Execute specialized catch on read
28262837 if self ._is_read :
28272838 if isinstance (exc , (ConnectionFailure , OperationFailure )):
@@ -2870,9 +2881,9 @@ async def run(self) -> T:
28702881 always_retryable = exc_to_check .has_error_label ("RetryableError" ) and overloaded
28712882
28722883 # Always retry abortTransaction and commitTransaction up to once
2873- if not ( self ._client . options . retry_writes and self . _retryable ) and (
2874- not always_retryable
2875- and self ._operation not in [ "abortTransaction" , "commitTransaction" ]
2884+ if self ._operation not in [ "abortTransaction" , "commitTransaction" ] and (
2885+ not self . _client . options . retry_writes
2886+ or not ( self ._retryable or always_retryable )
28762887 ):
28772888 raise
28782889 if retryable_write_label or always_retryable :
0 commit comments