我已经搜索了很长时间,但无法找到问题的解决方案.我们将SQLAlchemy与MySQL结合用于我们的项目,我们遇到了几次可怕的错误:
1213,'试图锁定时发现死锁; 尝试重启事务'.
在这种情况下,我们想尝试最多重启三次交易.
我已经开始编写一个装饰器来执行此操作,但我不知道如何在失败之前保存会话状态并在之后重试相同的事务?(因为SQLAlchemy在引发异常时需要回滚)
我到目前为止的工作,
def retry_on_deadlock_decorator(func):
lock_messages_error = ['Deadlock found', 'Lock wait timeout exceeded']
@wraps(func)
def wrapper(*args, **kwargs):
attempt_count = 0
while attempt_count < settings.MAXIMUM_RETRY_ON_DEADLOCK:
try:
return func(*args, **kwargs)
except OperationalError as e:
if any(msg in e.message for msg in lock_messages_error) \
and attempt_count <= settings.MAXIMUM_RETRY_ON_DEADLOCK:
logger.error('Deadlock detected. Trying sql transaction once more. Attempts count: %s'
% (attempt_count + 1))
else:
raise
attempt_count += 1
return wrapper
Run Code Online (Sandbox Code Playgroud) 我真的很努力地尝试使用 GRPC 文档的嵌入 retryPolicy(https://github.com/grpc/proposal/blob/master/A6-client-retries.md#retry-policy),但我不明白我应该在哪里在我的代码中设置配置。
理想情况下,我希望 python 客户端指定其重试策略,但我也有兴趣了解如何从服务器端管理它。
经过一番挖掘,我想出了这个剪断,但它不起作用。
import json
from grpc import insecure_channel
service_default_config = {
# see https://github.com/grpc/proposal/blob/master/A6-client-retries.md#retry-policy-capabilities
"retryPolicy": {
"maxAttempts": 5,
"initialBackoff": "1s",
"maxBackoff": "10s",
"backoffMultiplier": 2,
"retryableStatusCodes": [
"RESOURCE_EXHAUSTED",
"UNAVAILABLE"
]
}
}
service_default_config = json.dumps(service_default_config)
options = [
('grpc.service_config', service_default_config)
]
insecure_channel(hostname, options=options)
Run Code Online (Sandbox Code Playgroud)
谁能指出我的相关文档,让我了解这是如何工作的,或者向我解释我的误解?