1

我想创造功能。第一个是连接到数据库,如果第一个失败,第二个是完全重新连接。

在我的实验中,我在开始时关闭数据库以使connect块失败并调用重新连接块。之后我打开数据库,并期待连接块会成功,但我得到了异常。

这是我的代码:

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");
    }

    }

}

日志(几秒钟后打开数据库):

reconnection block
reconnection block
connection done
Reconnection to DB server done

object.Exception@C:\Users\Dima\AppData\Roaming\dub\packages\vibe-d-0.7.30\vibe-d\source\vibe\core\drivers\libevent2.d(326): Failed to connect to host 194.87.235.42:3306: Connection timed out [WSAETIMEDOUT ]

我不明白为什么我在之后得到异常:Reconnection to DB server done

4

1 回答 1

1

这里有两个主要问题。

首先,根本不需要自动重试尝试。如果它第一次不起作用,并且你没有改变任何东西,那么没有理由做同样的事情会在第二次突然起作用。如果您的网络如此不可靠,那么您将面临更大的问题。

其次,如果您要自动重试,那代码将不起作用:

一方面,在每次失败时reconnect调用connectTWICE:在循环体结束时调用一次,然后在循环条件下立即再次调用,无论连接是否成功。这可能不是你想要的。

但更重要的是,您在那里进行了潜在的无限递归:如果失败则connect调用。reconnect然后最多reconnect调用connect六次,每次都在失败时connect调用reconnectAGAIN ,永远循环,直到无法正常工作的连接配置以某种方式神奇地开始工作(或者更有可能,直到你破坏堆栈并崩溃)。

老实说,我建议把它全部扔掉:只需调用lockConnection(如果您使用 vibe.d)或new Connection(...)(如果您不使用 vibe.d)并完成它。如果您的连接设置有误,那么再次尝试相同的连接设置将无法修复它们。

lockConnection——应该有一个匹配的“解锁”吗?——里克·詹姆斯

不,有问题的连接池来自vibe.d。当锁定连接的光纤退出时(通常意味着“当您的服务器完成处理请求时”),任何被锁定的光纤连接都会自动返回到池中。

于 2017-02-16T05:11:33.833 回答