最近我参加了java面试,面试官问了如下问题:
我有一个请求,其中包括A,B,C模块和响应返回throgh A,在模块AI中需要与数据库通信并再次在模块CI中需要与数据库通信,所以在这种情况下有多少连接你将打开,你在哪里关闭这些联系?
我的答案:我说在模块AI中会打开一个连接然后我会关闭它,然后控制转到模块B然后模块C,再次在模块C中我将打开另一个连接,我将关闭它再次。然后他再问我一个问题,我想在每个请求处理中打开一个连接,我该怎么做?
答案 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实例中保持连接,以便可以在当前线程中共享它。不要使用简单的静态连接,否则它将在所有线程中共享并产生不希望的结果。