Использует ли мое приложение Java Hibernate пул подготовленных операторов? - PullRequest
0 голосов
/ 04 сентября 2018

Я использую базу данных Hibernate 4.3.11.Final и H2 1.3.172, и я профилировал свое приложение на медленном Linux-боксе и обнаружил, что оно тратит больше времени на определенный SQL INSERT, чем на что-либо другое. Также кажется, что подготовленные операторы не кэшируются, поскольку казалось, что количество подготовленных операторов было примерно таким же, как количество выполненных операторов.

Правильно ли я истолковал это право (я использую Yourkit Profiler)

enter image description here

Мой класс HibernateUtil настраивается следующим образом

public static Configuration getInitializedConfiguration()
    {
        Configuration config = new Configuration();

        config.setProperty(Environment.DRIVER,"org.h2.Driver");
        config.setProperty(Environment.URL,"jdbc:h2:"+Db.DBFOLDER+"/"+Db.DBNAME+";FILE_LOCK=SOCKET;MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE;CACHE_SIZE=50000");
        config.setProperty(Environment.DIALECT,"org.hibernate.dialect.H2Dialect");
        System.setProperty("h2.bindAddress", InetAddress.getLoopbackAddress().getHostAddress());
        config.setProperty("hibernate.connection.username","jaikoz");
        config.setProperty("hibernate.connection.password","jaikoz");
        config.setProperty("hibernate.c3p0.numHelperThreads","10");
        config.setProperty("hibernate.c3p0.min_size","20");
        //Consider that if we have lots of busy threads waiting on next stages could we possibly have alot of active
        //connections.
        config.setProperty("hibernate.c3p0.max_size","200");
        config.setProperty("hibernate.c3p0.timeout","300");
        config.setProperty("hibernate.c3p0.maxStatementsPerConnection","50");
        config.setProperty("hibernate.c3p0.idle_test_period","3000");
        config.setProperty("hibernate.c3p0.acquireRetryAttempts","10");
        addEntitiesToConfig(config);
        return config;
    }

Интересно, если я настроил это неправильно, то, что особенно запутанно, так это то, что документация c3po вполне сочетается с конфигурацией Hibernate относительно имени некоторых параметров.

то есть max_size или max_pool_size

Это однопользовательское многопоточное приложение, и в идеале я хочу, чтобы все подготовленные операторы кэшировались на время работы приложения, поскольку существует только около 50 различных операторов.

Как я понимаю каждый раз, когда я

session = HibernateUtil.beginTransaction();

, который получит соединение из пула, и если это конкретное соединение ранее подготовило оператор, который теперь требуется, то он может использовать этот подготовленный оператор без необходимости компилировать новый.

Если подготовленное утверждение не существует, то оно подготовлено.

Если к этому соединению уже подготовлено пятьдесят подготовленных утверждений, то самое старое будет удалено.

Этот конкретный запрос, который занимает больше времени, используется следующим образом

public static void saveMatchedToRelease(Session session,Integer reportId, Integer recNo, SongFieldKey songFieldKey, SongChangeType type, String original, String edited)
{
    SongChanges sc = new SongChanges();
    sc.setReportId(reportId);
    sc.setRecNo(recNo);
    sc.setField(songFieldKey);
    sc.setType(type);
    sc.setOriginalValue(original);
    sc.setNewValue(edited);
    session.save(sc);
}

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

В H2 подготовленные операторы кэшируются на уровне соединения. С hibernate.c3p0.max_size=200 существует вероятность того, что у вас будет так много открытых соединений, что каждый раз, когда пользователь выполняет операцию, он получает другое соединение H2.

Локальная в памяти H2 имеет минимальную стоимость подключения по сравнению с другими СУБД. Попробуйте удалить C3P0 и проверить с помощью одного соединения H2. Это должно подтвердить, что подготовленные операторы кэшируются драйвером JDBC.

В большинстве случаев меньше соединений лучше. В вашем случае, с одним пользователем и несколькими потоками, маловероятно, что ваша машина имеет 200 процессоров, чтобы в полной мере воспользоваться hibernate.c3p0.max_size=200.

0 голосов
/ 13 сентября 2018

Я не думаю, что кеширование - это проблема. Если вы открываете новую транзакцию при каждой вставке и всегда вставляете в таблицу песен разные потоки, возможно, вы блокируете себя открытыми транзакциями. Многопоточность может легко привести к ошибкам, особенно при открытых транзакциях базы данных.

...