Ошибка таймаута, пытающаяся заблокировать таблицу в 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
Ответы
Ответ 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();