2727
2828from neo4j .bolt import ProtocolError , ServiceUnavailable
2929from neo4j .compat import urlparse
30- from neo4j .exceptions import CypherError
30+ from neo4j .exceptions import CypherError , TransientError
3131
3232from .exceptions import DriverError , SessionError , SessionExpired , TransactionError
3333
34-
3534_warned_about_transaction_bookmarks = False
3635
37-
3836READ_ACCESS = "READ"
3937WRITE_ACCESS = "WRITE"
4038
@@ -53,7 +51,6 @@ def retry_delay_generator(initial_delay, multiplier, jitter_factor):
5351
5452
5553class ValueSystem (object ):
56-
5754 def hydrate (self , values ):
5855 """ Hydrate values from raw representations into client objects.
5956 """
@@ -435,6 +432,11 @@ def _run_transaction(self, access_mode, unit_of_work, *args, **kwargs):
435432 return unit_of_work (tx , * args , ** kwargs )
436433 except (ServiceUnavailable , SessionExpired ) as error :
437434 last_error = error
435+ except TransientError as error :
436+ if is_retriable_transientError (error ):
437+ last_error = error
438+ else :
439+ raise error
438440 sleep (next (retry_delay ))
439441 t1 = clock ()
440442 raise last_error
@@ -461,6 +463,17 @@ def __bookmark__(self, result):
461463 pass
462464
463465
466+ def is_retriable_transientError (error ):
467+ """
468+ :type error: TransientError
469+ """
470+ if (error .code != "Neo.TransientError.Transaction.Terminated"
471+ and error .code != "Neo.TransientError.Transaction.LockClientStopped" ):
472+ return True
473+ else :
474+ return False
475+
476+
464477class Transaction (object ):
465478 """ Container for multiple Cypher queries to be executed within
466479 a single context. Transactions can be used within a :py:const:`with`
0 commit comments