Подтвердить что ты не робот

Ошибка таймаута, пытающаяся заблокировать таблицу в h2

Я получаю следующую ошибку при определенном сценарии

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

Env: h2 (последний), Hibernate 3.3.x

Caused by: org.h2.jdbc.JdbcSQLException: Timeout trying to lock table "USER"; SQL statement:

[50200-144]

    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
    at org.h2.message.DbException.get(DbException.java:167)
    at org.h2.message.DbException.get(DbException.java:144)
    at org.h2.table.RegularTable.doLock(RegularTable.java:482)
    at org.h2.table.RegularTable.lock(RegularTable.java:416)
    at org.h2.table.TableFilter.lock(TableFilter.java:139)
    at org.h2.command.dml.Select.queryWithoutCache(Select.java:571)
    at org.h2.command.dml.Query.query(Query.java:257)
    at org.h2.command.dml.Query.query(Query.java:227)
    at org.h2.command.CommandContainer.query(CommandContainer.java:78)
    at org.h2.command.Command.executeQuery(Command.java:132)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:278)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:137)
    at java.lang.Thread.run(Thread.java:619)
    at org.h2.engine.SessionRemote.done(SessionRemote.java:543)
    at org.h2.command.CommandRemote.executeQuery(CommandRemote.java:152)
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)
    at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:342)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2228)
    ... 125 more
4b9b3361

Ответ 1

Да, вы можете изменить тайм-аут блокировки. Значение по умолчанию относительно низкое: 1 секунда (1000 мс).

Во многих случаях проблема заключается в том, что другое соединение заблокировало таблицу, и использование многостраничной версии concurrency также решает проблему (добавьте ;MVCC=true к URL-адресу базы данных).

Ответ 2

Я столкнулся с такой же проблемой и использовал параметр "MVCC = true", он решил это. Подробнее об этом параметре можно найти в документации по H2: http://www.h2database.com/html/advanced.html#mvcc

Ответ 3

Я хотел бы предположить, что если вы получаете эту ошибку, то , возможно, вы не должны использовать транзакцию в своей операции с массовой базой данных. Рассмотрите возможность совершения транзакции для каждого отдельного обновления: имеет ли смысл думать о полном объеме импорта в качестве транзакции? Возможно нет. Если да, то да, MVCC = true или большой тайм-аут блокировки - разумное решение.

Однако, я думаю, что в большинстве случаев вы видите эту ошибку, потому что пытаетесь выполнить очень длинную транзакцию - другими словами, вы не знаете, что выполняете действительно длительную транзакцию. Это, безусловно, было для меня, и я просто заботился о том, как я писал записи (либо без транзакций, либо с использованием небольших транзакций), и проблема тайм-аута блокировки была решена.

Ответ 4

Для тех, у кого есть эта проблема с интеграционными тестами (т.е. сервер обращается к h2 db, а тест интеграции обращается к db перед вызовом сервера, чтобы подготовить тест), добавив "commit" к script, выполненному до тест гарантирует, что данные находятся в базе данных до вызова сервера (без MVCC = true - который я нахожу немного "странным", если он по умолчанию не включен).

Ответ 5

У меня возникла проблема с PlayFramework

Возникло событие JPAQueryException: ошибка при выполнении запроса из models.Page где name =?: Таймаут, пытающийся заблокировать таблицу "PAGE"

Он закончился бесконечным циклом, потому что у меня был

@Before

без if, заставляя функцию многократно называть себя

@Before (если = "GetUser" )

Ответ 6

Работа с DBUnit, H2 и Hibernate - та же ошибка, MVCC = true, но я все равно получаю ошибку для любых тестов после удаления данных. Исправленные эти случаи заключались в упаковке фактического кода удаления внутри транзакции:

Transaction tx = session.beginTransaction();
...delete stuff
tx.commit();