В идеале, сколько соединений мне нужно открыть? - PullRequest
3 голосов
/ 18 мая 2010

Недавно я посетил интервью в Java, интервьюер задал вопрос, как показано ниже:

У меня есть запрос, который идет через модули A, B, C, и ответ идет назад через A, в модуле AI нужно общаться с базой данных, и снова в модуле C мне нужно общаться с базой данных, поэтому в этой ситуации, сколько соединений вы откроется и где вы закрываете эти соединения?

Мой ответ: Я сказал, что в модуле AI откроет соединение, и я тут же закрою его, затем перейдите к модулю B, затем к модулю C, в модуле C снова открою еще одно соединение и закрою его снова. Затем он задал мне еще один вопрос. Я хочу открыть одно соединение на одну обработку запроса. Как я могу это сделать?

Ответы [ 5 ]

4 голосов
/ 18 мая 2010

Совместное использование соединения в модулях.

EDIT Вы можете поделиться подключением, передав его различным модулям:

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 );
    }
}
3 голосов
/ 18 мая 2010

Я полагаю, что ответ, который он искал, состоял в том, чтобы использовать ThreadLocal и завершить его в фильтре в конце запроса, но сложно выбрать «лучшее» решение, не задавая больше вопросов об архитектуре. указанная область модулей завернута в (и даже в контекстное значение слова module.)

1 голос
/ 18 мая 2010

Используйте пул соединений с базой данных, такой как apache dbcp http://commons.apache.org/dbcp/

1 голос
/ 18 мая 2010

Например, используя решение ORM, такое как Hibernate, вы можете оставить текущий сеанс (который является своего рода высокоуровневым эквивалентом соединения Hibernate) открытым в течение всего времени существования запроса и использовать его во всех модули.

0 голосов
/ 19 мая 2010

«В идеале, сколько соединений мне нужно открыть?»

Это очень просто: открыть одно соединение на запрос (независимо от того, через сколько модулей он проходит), а затем закрыть соединение, когда запрос завершен.

"Затем он снова задал мне еще один вопрос. Я хочу открыть одно соединение на одну обработку запроса, как я могу это сделать?"

Создать фильтр (перехватчик запросов), который открывает соединение перед обработкой запроса и закрывается после него. Сохраняйте соединение в статическом экземпляре ThreadLocal, чтобы его можно было использовать в текущем потоке. Не используйте простое статическое соединение, иначе оно будет доступно всем вашим потокам и приведет к нежелательным результатам.

...