2010-05-18 51 views
3

最近我参加了在Java面试,面试官问类似下面一个问题:理想情况下我必须打开多少个连接?

我有去throgh A,B,C模块和响应回去throgh一个请求,在模块AI需要跟数据库再次在模块CI中需要与数据库交谈,所以在这种情况下您将打开多少个连接,以及您在哪里关闭这些连接?

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

+0

连接是否应该是单线程?模块C可以独立提交/回滚吗? – Uri 2010-05-18 19:32:29

+0

如果您获得1000请求,则不应创建超过1000个到数据库的连接,您应该只创建<= 1000个连接。所以在这种情况下,单个线程概念如何来到这里,我不知道它。你可以详细说明你的意思是什么“单线程” 模块C可以独立提交/回滚 – Ranjith 2010-05-18 19:41:03

+0

@ Ranjith-kumar-u有一种机制可以在一个线程中共享“数据”,这就是Thread-local是关于。您可以将连接存储在那里,并让任何人使用它在同一个线程中。 – OscarRyz 2010-05-18 19:43:56

回答

4

共享的模块的连接。

编辑 您可以通过它传递给不同的模块共享的连接:

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

您也可以在外部类的连接,并在需要时进行搜索(也许使用一个会话ID)

我不知道这是否算作“连接池”

这里反正就是这样。

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); 
    } 
} 
+0

如何做到这一点?我不应该在这里使用任何连接池技术。 – Ranjith 2010-05-18 19:29:44

+0

听起来像一个设计模式。有没有这个名字? – Pretzel 2010-05-18 19:30:45

+0

存储库模式? – Pretzel 2010-05-18 19:37:35

1

例如,通过使用像Hibernate的ORM解决方案,可以保持当前会议(这是排序更高层次的Hibernate等值连接的)在整个请求生命周期开放,并在所有使用它模块。

3

我猜他一直在寻找的答案是使用一个ThreadLocal并在请求结束的过滤器终止它,但它是艰难的决定在没有询问架构更多的问题“最好”的解决方案所述模块区域包裹起来(甚至在字模块的上下文中的含义。)

0

“我理想的情况下多少个连接都开?”

它非常简单,每个请求打开一个连接(不管多少模块经过),然后关闭连接请求完成时。

“然后他问我再次另一个问题,我想打开每请求处理一个连接,我怎么能这样做呢?”

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