我想创建函数。第一个是连接到DB,如果第一个失败,第二个是完全重新连接。
在我的实验中,我一开始就关闭DB,以获得connect
块失败并调用重新连接块。在它之后,我打开DB,并期待连接块会成功,但我得到了例外。
这是我的代码:
bool connect()
{
if(connection is null)
{
scope(failure) reconnect(); // call reconnect if fail
this.connection = mydb.lockConnection();
writeln("connection done");
return true;
}
else
return false;
}
void reconnect()
{
writeln("reconnection block");
if(connection is null)
{
while(!connect) // continue till connection will not be established
{
Thread.sleep(3.seconds);
connectionsAttempts++;
logError("Connection to DB is not active...");
logError("Reconnection to DB attempt: %s", connectionsAttempts);
connect();
}
if(connection !is null)
{
logWarn("Reconnection to DB server done");
}
}
}
日志(几秒钟后打开DB):
reconnection block
reconnection block
connection done
Reconnection to DB server done
object.Exception@C:UsersDimaAppDataRoamingdubpackagesvibe-d-0.7.30vibe-dsourcevibecoredriverslibevent2.d(326): Failed to connect to host 194.87.235.42:3306: Connection timed out [WSAETIMEDOUT ]
我不明白为什么在Reconnection to DB server done
之后出现异常
这里有两个主要问题。
首先,根本不需要自动重试。如果第一次不起作用,而且你没有改变任何事情,那么做同样的事情没有理由在第二次突然起作用。如果你的网络如此不可靠,那么你就会遇到更大的问题。
其次,如果你无论如何都要自动重试,那就是代码不起作用:
首先,reconnect
在每次失败时都会调用connect
两次:在循环体结束时调用一次,然后在循环条件下立即再次,无论连接是否成功。这可能不是你想要的。
但更重要的是,这里有一个潜在的无限递归:如果失败,connect
将调用reconnect
。然后,reconnect
最多调用connect
六次,每次connect
在失败时再次调用reconnect
,永远循环,直到不起作用的连接配置神奇地开始工作(或者更有可能,直到你破坏堆栈并崩溃)。
老实说,我建议你把这一切都扔掉:只要打电话给lockConnection
(如果你使用的是vibe.d)或new Connection(...)
(如果你没有使用vib.d)就可以了。如果你的连接设置错误,那么再次尝试相同的连接设置是无法修复的。
lockConnection——是否应该有匹配的"解锁"?-Rick James
不,有问题的连接池来自vibe.d。当锁定连接的光纤退出时(通常意味着"当服务器处理完请求时"),光纤锁定的任何连接都会自动返回到池中。