【PW C++】长时间连续运行会话问题

我们编制了一个服务用来操作PW,该服务长时间运行后(十几个小时)开始报错(执行普通SQL语句aaApi_SqlSelect,SQL语句没有问题,会循环执行),错误信息为:Database communication error,接着再报:Datasource connection terminated。但这个时候调用aaApi_IsConnectionLost()返回的又是false,再调用aaApi_GetCurrentSession获取的会话ID跟登录成功的也一样,但执行SQL语句就依次报上面提到的两个错误。后面通过aaApi_LogoutByHandle退出登录后,再调用aaApi_Login也登录不起,报的错误信息:

错误信息:Cannot login to the datasource
详细信息:Failed to connect to the remote server application.

如果想长时间不间断运行有什么好的解决办法呢?

  • 我们可以用替换排查法来做一个初步的判断:就是自己写一个与PW无关的独立的数据库操作程序,模拟你在aaApi_xxx中所做的数据库操作。看长时间运行后是否数据库仍然稳定运行。



  • 数据库连接都有时限限制(空闲时),过了应该通过重新登录可以再次连接上

  • 那有可能是aaApi没有考虑到这种超过时限的情况。你可以要么延长数据库连接时限的设置,要么在时限到达前主动调用aaApi的Logout登出,再重新登入。



  • 我现在每4个小时重新登录一次,到了凌晨2-3点再出上面错就再也登录不成功了(这个时间点是否有特殊操作在进行,其他时间点出上面错误再登录都正常)。后面我开发一个新服务专门监控这个服务遇到登录不起的时候就重启服务但重启后还是登录不起,对于这种连续长时间运行PW程序到底需要怎么处理呢?有什么好解决方案呢?

  • PW作为后台服务没有问题的,连续跑几个月没有问题的,只要有操作到API,登录就不会过期,当然每个循环再登录一次也行。问题估计还是出在你的后台服务的代码逻辑上,是否有变量被回收可能,或者长时间没有操作,登录过期或者是否有多线程操作的情况。而登录不上,确定PW服务是正常的和数据库通信是正常的?

    以C#后台服务为例,逻辑代码供参考:

    public Service1()
    {

    .......

    protected override void OnStart(string[] args)
    {

    .......

    MonitorTimer = new System.Timers.Timer();
    MonitorTimer.Interval = Interval_Monitor * 1000;
    MonitorTimer.AutoReset = true;
    MonitorTimer.Enabled = true;
    MonitorTimer.Elapsed += new System.Timers.ElapsedEventHandler(MonitorStartProc);
    MonitorTimer.Start();

    }

    protected void MonitorStartProc(object source, System.Timers.ElapsedEventArgs e)
    {

    ......


    LogWrite("开始运行第 " + RunCount.ToString() + " 次");


    SyncData();


    ....

    }

    public void SyncData()
    {

    //开始登录,然后开始处理.
    bool loginlret = LoginDBSource(dbnode);
    //登录成功开始处理
    if (!loginlret)
    {
    continue;
    }

    .

    ...to do something....

    }

    public bool LoginDBSource(XmlNode dbNode)
    {
    try
    {
    ........

    DBSourceFun.aaApi_Initialize(0);
    bool lRetVal = DBSourceFun.aaApi_AdminLogin(0, dbstr, username, password);
    if (lRetVal)
    {
    LogWrite("@@@@@@@@@@@@@@@@@@登录数据源成功:" + dbsourcename);
    }
    else
    {
    LogWrite("登录数据源失败:" + dbsourcename + " 原因:" + DBSourceFun.aaApi_GetLastErrorDetail());
    return false;
    }

    ......return true;


    }
    catch (Exception ex)
    {
    LogWrite(ex.ToString());
    return false;
    }
    }