理想情况下我必须打开多少个连接?

时间:2010-05-18 19:24:28

标签: java database-connection

最近我参加了java面试,面试官问了如下问题:

我有一个请求,其中包括A,B,C模块和响应返回throgh A,在模块AI中需要与数据库通信并再次在模块CI中需要与数据库通信,所以在这种情况下有多少连接你将打开,你在哪里关闭这些联系?

我的答案:我说在模块AI中会打开一个连接然后我会关闭它,然后控制转到模块B然后模块C,再次在模块C中我将打开另一个连接,我将关闭它再次。然后他再问我一个问题,我想在每个请求处理中打开一个连接,我该怎么做?

5 个答案:

答案 0 :(得分:4)

在模块中共享连接。

修改 您可以通过将连接传递给不同的模块来共享连接:

class ModuleA {
    void process(){
        Connection c = getConnection();
        doA();
        new ModuleB( c ).doBs();
        new ModuleC( c ).doCs();
        doSomeMoreA();
        c.close();
    }
}

您还可以在外部类中建立连接并在需要时搜索它(可能使用sessionid)

我不确定这是否算作“连接池”

无论如何都是这样。

class Db {
    private static Map<Integer, Connection> map;

    public static Connection getConnection( int sessionId ){

        if( !map.containsKey( sessionId ) ) {
            map.put( sessionId, createConnection());
        }
        return map.get( sessionId );
    }
}
class Main {
    void processs() {
        int sessionId = createSesionId();
        ModuleA a = new ModuleA( sessionId );
        a.doAsStuff();
        ModuleB b = new ModuleB( sessionId );
        b.doBsStuff();
        ModuleC c = new ModuleC( sessionId );
        b.doCsStuff();
        a.closeTransaction();

    }
}
class ModuleA{

    public doAsStuff() {
        Connection c = Db.getConnection(sessionId);
        doSomethingWith( c );
    }
    public closeTransaction() {
        Connection c = Db.getConnection(sessionId);
        c.close();
    }
}
class ModuleB{

    public doBsStuff() {
        Connection c = Db.getConnection(sessionId);
        doSomethingWith( c );
    }
}
class ModuleC{

    public doCsStuff() {
        Connection c = Db.getConnection(sessionId);
        doSomethingWith( c );
    }
}

答案 1 :(得分:3)

我猜他正在寻找的答案是使用ThreadLocal并在请求结束时在过滤器中终止它,但很难在没有询问更多问题的情况下决定“最佳”解决方案架构说模块区域包含在内。(甚至是单词模块的上下文含义。)

答案 2 :(得分:1)

例如,通过使用像Hibernate这样的ORM解决方案,您可以在整个请求生命周期内保持当前会话(这是一种更高级别的Hibernate等效连接),并将其用于所有模块。

答案 3 :(得分:1)

使用数据库连接池,例如apache dbcp http://commons.apache.org/dbcp/

答案 4 :(得分:0)

“理想情况下我必须打开多少个连接?”

每个请求非常简单,开放的一个连接(无论它通过多少个模块),然后在请求完成时关闭连接。

“然后他再问我一个问题,我想在每个请求处理中打开一个连接,我该怎么做?”

创建一个过滤器(请求拦截器),在处理请求之前打开一个连接,然后关闭。在静态ThreadLocal实例中保持连接,以便可以在当前线程中共享它。不要使用简单的静态连接,否则它将在所有线程中共享并产生不希望的结果。