发现问题
    前些日子维护编写的通讯服务器时遇到了这么一个问题:在通讯服务器里有一个数据库连接池,为他人提供数据库连接服务,结果发现在使用过程中连接有时会耗尽,这个问题通过调试跟踪发现,有“客户”在使用数据库连接时,总是不释放连接(已提供了释放连接的方法)。其实问题很好解决,找出未释放连接的那个“客户”然后按照GetConnection,ReleaseConnection的方式来正确调用就可以了。

解决问题?
    但是找出那个“客户”很容易吗?看看我们的整个系统吧,多达五个子系统插件在使用这个服务,而且其中的数据库连接调用很多,这样找可费了大劲了。在经过大量的代码审核后,终于找出未释放连接的那个客户,解决了这个问题。


思考之下,作为一个关键的公共服务是不是可以做相应优化来应对这种“客户”犯下的错误。

采用RAII机制,把释放链接的那个方法也写入析构函数中
    举例(采用伪码加不标准类写法方式,主要是说明思路;参考effective c++章节2 构造/析构)
class ConnectionPool
{
public:

  ...

  ~ConnectionPool(void);
  {
    if (!bRelease)
    {
      Release连接();
    }
  }

  void  ReleaseConnection()
  {
    Release连接();
    bRelease = true;
  }
private:

  bool  bRelease;     (初始化为false)
};

这样”客户“如果是采用栈或智能指针实例化的对象来使用服务,即使忘记释放连接都可以利用RAII机制安全释放;

但是如果”客户“直接用new出的对象使用服务忘记释放连接呢,又回到了最先遇到的问题上,在一大推调用里找究竟是谁未释放连接。继续解决:
    既然现在我们的困扰集中在找违规”客户“的麻烦上,想想图书馆借书,谁借去了必须把他的名字登记下来,谁谁谁借走了这本书,到时候即使他不还,咱也有办法找到他让他给咱还回来。于是我们可以再改造一下这个服务,在每个”客户“获得连接时都传入他的标识然后把这个连接和标识捆绑起来。这样,哪个”客户“未释放连接一目了然了吧,立马找到他让他改正。OK,快速解决。