2013-02-06 47 views
1

我已经实现了连接池。一切都很好。现在,如果一个客户借用一个连接,甚至将其返回到池中,但客户端也保持与他的连接的参考。现在,如果池返回与另一个客户端相同的连接,这将导致多人使用相同的连接。避免客户端在实现连接时保持连接的引用池

我该如何避免这种情况?

回答

1

不要返回底层连接对象,而是返回包装它的另一个对象。在该对象内(使用某种私有属性)存储该对象的状态;是否仍然可以使用,还是因为被退回游泳池或其他条件(如超时)而失效)。然后你可以拦截任何尝试使用它的方法调用并检查它的状态。如果它不再可用,则抛出异常。

包装的连接对象也需要是私有的,这样客户端才能直接访问它。

每个客户端都有一个包装器,但两个或多个包装器可能共享底层连接对象。但是,由于每个客户端都在存储状态,因此一次只能有一个客户端使用该对象。

修改为包含一个未经测试的示例 - 该示例现在显示了我的方法存在的一个大问题。

假设你正在返回一些实现了java.sql.Connection的东西,你可以返回下面类的实例。

package same.package.as.your.pool; // so your pool has access to set isValidConnection 

import java.sql.Connection; 

class MyConnection implements Connection { 
    private Connection actualConnection; 
    private boolean isValidConnection = false; 

    MyConnection(Connection conn) { 
     // package acccess for pool class to create connection 
     actualConnection = conn; 
     isValidConnection = true; 
    } 

    public boolean getIsValidConnection() { 
     return isValidConnection; 
    } 

    void setIsValidConnection(boolean isValid) { 
     // pool class can call this to invalidate when returned to pool or timed out 
     isValidConnection = isValid; 
    } 

    // intercept java.sql.Connection methods, checking if connection is still valid first 
    // for example 
    PreparedStatement prepareStatement(String sql) { 
     if (! isValidConnection) { 
      // WHAT TO DO HERE? 
     } 
     return actualConnection.prepareStatement(sql); 

    } 

    // ... and the rest 

第一个大问题就是 - 最好你会当连接不再有效,因为它已经返回到池塘里扔从像prepareStatement方法异常。但是由于受到捕获的原始接口异常的限制(在本例中抛出SQLException),您需要抛出一个SQLException(yuk,它实际上不是一个SQLException)或一个未捕获的异常(yuk - 客户机代码可能想要捕捉连接池不再有效的情况)或其他: - )

上述代码的两个其他问题 - 用于保护只​​能用于池代码的方法的包访问是不是很健壮。也许你可以创建MyConnection代码作为池代码中的某种内部类。最后,必须重写全部 java.sql.Connection接口将会很痛苦。

}

+0

我不确定这是如何“真实”的连接池做到这一点,只是我的想法如何处理它。 –

+0

你可以举个例子!我了解包装对象;但即使返回object()。getConnection()返回该对象;客户端仍然可以参考。 – Deepak

+0

你正在返回的类实例不应该有getConnection()。 –