有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java避免客户端在实现连接池时保留对连接的引用

我已经实现了一个连接池。一切都很好。现在,如果客户机借用了一个连接,甚至将其返回到池中,但客户机也会将该连接的引用保存在自己的身上。现在,如果池返回到另一个客户端的相同连接;这将导致多人使用相同的连接

我怎样才能避免呢


共 (1) 个答案

  1. # 1 楼答案

    不要返回基础连接对象,而是返回包装它的另一个对象。在该对象内(使用某种私有财产)存储该对象的状态;它是否仍然可以使用,或者是否由于返回到池或某些其他条件(如超时)而无效。然后,您可以拦截任何试图使用它的方法调用,并检查其状态。如果它不再可用,则引发异常

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

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

    编辑后包含了一个未经测试的示例-现在显示了我的方法的一个大问题

    假设您返回的是实现java的东西。sql。连接时,可以返回以下类的实例

    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代码作为某种内部类。最后,必须重写alljava。sql。连接接口将是一种痛苦

    }