2012-02-08 58 views
2

我有一个数据库连接池。有消费者从该游泳池获取连接。 但我不能相信这些消费者,因为他们中的很多人都没有返回我的连接。因此游泳池挨饿,许多消费者被迫等待无限。 例如:消费者没有返回连接到我的数据库连接池

class Consumer{ 
    void someMethod(){ 
     Connection con=Pool.getConnection(); 
     //some bloody steps which throws exception 
     con.goodBye();//giving back the connection to the pool 
    } 
} 

由于异常的,可能是因为傲慢的连接没有给予回复永远的。我无法限制消费者阶层使用Pool api。 (我没有办法强制消费者) 我相信这里没有傻瓜证明的解决方案(可能不是那么聪明)。任何人都可以想出一个很好的解决方案。 我得到的一个解决方案是检查消费者类是否发生任何异常,如果发生异常,然后完全收回连接力。

或者是否有任何新的革命性DBPool设计模式在这种典型场景中不是非常流行(即使我认为我的案例非常通用,任何人都可以忘记将连接还给池。 )

+2

这比编程更为行政/管理问题。你无法解决世界上坐在隔间和编码中的所有麻烦。对于这一个,我会编制一个可怜的程序客户名单,并提出与他们的管理这个问题。 – 2012-02-08 13:31:28

回答

1

不要返回连接对象,而是返回代表连接的代理对象。这些代理对象最终确定后,应告别他们所代表的连接。如果代理未正确关闭,它最终将被垃圾回收,并在此时调整连接状态。

这里有两个问题。首先,GC之前的时间是不可预测的。比永远好,但仍然可以很长。其次,要注意终结器中复杂调用的副作用,特别是对象复活。有一些罕见但丑陋的场景阻止收集对象。

+0

我认为这个解决方案是最不重要的 – Arshed 2012-02-09 06:54:32

0

您是否试图捕获异常并关闭catch子句中的连接?

class Consumer{ 
    void someMethod(){ 
     Connection con=Pool.getConnection(); 
     try{ 
      //some bloody steps which throws exception 
     }catch(Exception e){ 
      con.goodBye(); 
     } 
     con.goodBye();//giving back the connection to the pool 
    } 
} 

编辑:你也可以使用一个finally块去除冗余代码,并确保您的连接会在任何情况下关闭。我假设这是Java代码,没有C#的经验。

+0

我同意你的意见。但不幸的是,消费者部分是由外部用户实现的。我的意思是我提供了Pool API,并提供给消费者使用它。 – Arshed 2012-02-08 13:07:55

+1

@Arshed然后这不是你的责任。您已经提供了一个完善的api,消费者会故意忽略它。 – 2012-02-08 13:15:50

+0

案例就是这样。有一个mysql(或任何DB)数据库。这个mysql有'N'no数据库。我有客户/客户。他们连接到他们各自的数据库起诉我的游泳池。 Client1采取一些连接并永远不会返回,不应该影响Client2。我同意,让客户1因为他的罪而受苦。但为什么客户端2 – Arshed 2012-02-08 13:19:50

0

我能想到的唯一方法不是让消费者直接访问连接池,而是拥有自己的连接列表。然后在超时后回收连接,例如60秒。

+0

我该怎么做?当时消费者可能正在做一些交易,如果我这样做会导致系统不稳定。 – Arshed 2012-02-08 13:11:11

+0

应该有一个超时,是的。但是,如果超时时间太短,您还会遇到其他问题。而且大多数连接池机制都不会“直接”暴露池,无论如何......这就是关键。 – 2012-02-08 13:12:31

+0

首先,您的系统此刻听起来不稳定。如果消费者真正在建立关系超过一分钟,您可能需要增加时间(我似乎记得谷歌强加30秒限制的一些事情)。 Pool.getConnection();在你的控制下?你会重新定义这个从列表中获得连接,而不是直接从池中获得连接。 – Jaydee 2012-02-08 13:48:54

2

这是糟糕的客户端代码。代码应处理异常情况,并在完成时关闭连接。

虽然没有办法让你从代码中知道是否还没有完成。这是客户端代码的错误和问题,如果它不这样做。

有一个理智的超时是限制这种情况的唯一方法,但它最终还是不能“解决”它。

-

您在留言内提及,这池多个客户端之间共享。当然,这将责任转移回给你。

你可以限制每个客户端只使用X连接吗?这样,至少他们一次只能绑定很多人。

否则,您可以为每个客户端创建单独的池。这类问题只是将问题向下推进,但可能是合适的,具体取决于所涉及的物流。

+0

考虑这种情况。 我同意你的意见。该特定客户端存在故障。但有n个客户,如果1个客户做错了一些事情,它不应该影响其他客户 – Arshed 2012-02-08 13:13:26

+0

我会编辑我的答案来反映。 – 2012-02-08 13:18:35

+0

我可以限制特定客户端的连接数量。但它不能解决问题。单独的独立游泳池将解决问题。但我认为它不实用。即使有太多的空闲连接(分配给其他客户端),我也会限制允许连接到特定客户端的连接数量。 – Arshed 2012-02-08 13:29:15

1

你为什么不看看使用WeakReference,在这里你可以调整你的代码来返回一个弱连接的连接,当线程使用连接死亡时,对象将没有参考(除了你的WeakHashMap),您可以定期识别这些对象,并使用线程调用goodBye方法。

here是一篇文章,可以帮助您更好地理解这一点。

.net也有一个WeakReference类,其行为非常类似于此。

+1

我怀疑这在这种情况下可能没有帮助。它基本上实现了连接超时,但具有与通常使用的模式不同的模式。 – 2012-02-08 13:25:31

+0

是的,我同意,这里的麻烦是当客户不遵守标准,你仍然可以做一些事情来跟踪事情..这是一种做法..我同意它的一个方式,但它在几种情况下为我工作。 – 2012-02-08 13:42:53

+1

我认为这是一个好主意。谢谢 – Arshed 2012-02-08 13:52:36