<p>这个例子有点粗糙,但有希望展示了处理断开连接的逻辑。具体细节取决于在特定框架中获得连接的方式。在</p>
<p>下面的代码假定使用<a href="https://pypi.python.org/pypi/retry" rel="nofollow noreferrer">^{<cd1>}</a>;如果需要,可以使用不同的重试逻辑。在</p>
<p>它还假设您正在使用框架提供的应用程序的连接池。通常,您可以请求它重新连接,或者至少关闭空闲连接,以便另一个连接请求将创建一个新的连接请求。在</p>
<pre><code>def reconnect_on_failure(func):
@retry(OperationalError, delay=0.25, backoff=1.5, max_delay=5)
@wraps(func)
def reconnecting_func(*args, **kwargs):
try:
return func(*args, **kwargs)
except OperationalError as e:
if 'connect' in e.msg.lower():
force_reconnection_somehow() # Look at your connection pool API.
raise # We want to retry on it
raise Exception('Unhandled MySQL error', e) # Will not retry.
return reconnecting_func
@reconnect_on_failure
def something(...):
connection = get_connecton_somehow() # Look at the framework API.
# A transaction implicitly begins with the first statement executed.
cursor = connection.cursor()
result = cursor.execute(...) # do stuff
connection.commit()
</code></pre>
<p>代替过于宽泛的<code>Exception</code>,您可以使用一个更窄的类,例如针对您的应用程序;其思想是,引发任何<em>但</em><code>OperationalError</code>不会触发重试,它将立即引发一个<code>Exception</code>来报告问题。在</p>
<p><strong>从Grender编辑:</strong>我添加了<a href="https://docs.python.org/2/library/functools.html#functools.wraps" rel="nofollow noreferrer">^{<cd5>}</a>装饰器,以避免<code>AssertionError</code>如{a3}所示。在</p>