java - 如何避免 Flyway Migrations 锁定 SQLite 数据库?

标签 java sqlite flyway

我们使用 SQLite 进行 Flyway 迁移 (Flyway v3.2.1、SQLite 3.7.13 和 org.xerial:sqlite-jdbc:3.8.7 驱动程序。)

并行数据库连接的最大数量似乎是至关重要的。但是由于不同的原因,任何连接池大小的迁移都会失败。

1。使用大小为 2 或更大的连接池

存在与多个并行数据库连接相关的锁定问题。 空 SQLite 数据库上的单个迁移以:

o.f.core.internal.command.DbMigrate.(:)()  Current version of schema "main": << Empty Schema >>
o.f.core.internal.command.DbMigrate.(:)()  Migrating schema "main" to version 1 - initial
o.f.c.i.u.jdbc.TransactionTemplate.(:)()  Unable to restore autocommit to original value for connection
java.sql.SQLException: database is locked
    at org.sqlite.core.DB.throwex(DB.java:859) ~[sqlite-jdbc-3.8.7.jar:na]
    at org.sqlite.core.DB.exec(DB.java:142) ~[sqlite-jdbc-3.8.7.jar:na]
    at org.sqlite.jdbc3.JDBC3Connection.setAutoCommit(JDBC3Connection.java:152) ~[sqlite-jdbc-3.8.7.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_71]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_71]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_71]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_71]
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) ~[tomcat-jdbc-7.0.56.jar:na]
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) ~[tomcat-jdbc-7.0.56.jar:na]
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:80) ~[tomcat-jdbc-7.0.56.jar:na]
    at com.sun.proxy.$Proxy76.setAutoCommit(Unknown Source) ~[na:na]
    at org.flywaydb.core.internal.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:96) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.internal.command.DbMigrate.applyMigration(DbMigrate.java:282) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.internal.command.DbMigrate.access$800(DbMigrate.java:46) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.internal.command.DbMigrate$2.doInTransaction(DbMigrate.java:207) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.internal.command.DbMigrate$2.doInTransaction(DbMigrate.java:156) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.internal.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:72) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.internal.command.DbMigrate.migrate(DbMigrate.java:156) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.Flyway$1.execute(Flyway.java:1059) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.Flyway$1.execute(Flyway.java:1006) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.Flyway.execute(Flyway.java:1418) [flyway-core-3.2.1.jar:na]
    at org.flywaydb.core.Flyway.migrate(Flyway.java:1006) [flyway-core-3.2.1.jar:na]
    ...

这似乎是一个普遍的 SQLite 陷阱,如所述 here .

通常,Flyway 迁移以及我们剩余的应用程序都会遇到这种类型的频繁锁定错误:

java.sql.SQLException: [SQLITE_BUSY] The database file is locked

当两个或多个连接处于 Activity 状态时。这就是为什么我们尝试......

2。 ...使用大小为 1 的连接池

我们将并行数据库连接的数量减少到一个(通过使用“maxActive=1”配置我们的 Tomcat JDBC 连接池)。

但是现在,Flyway 失败了

 ... org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
    at org.flywaydb.core.internal.util.jdbc.JdbcUtils.openConnection(JdbcUtils.java:56)
    at org.flywaydb.core.Flyway.execute(Flyway.java:1386)
    at org.flywaydb.core.Flyway.migrate(Flyway.java:1006)
    (...)
Caused by: org.apache.tomcat.jdbc.pool.PoolExhaustedException: [localhost-startStop-1] Timeout: Pool empty. Unable to fetch a connection in 10 seconds, none available[size:1; busy:1; idle:0; lastwait:10000].
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:674)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:188)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
    at org.flywaydb.core.internal.util.jdbc.JdbcUtils.openConnection(JdbcUtils.java:50)

为什么? Flyway 迁移似乎需要两个并行连接。 Here他们有一个相关的问题并说: “Flyway 似乎至少使用了两个连接:一个用于锁定 schema_version 表,一个用于实际运行更改……”


最后,我想知道 Flyway 是如何支持 SQLite 的。两个连接是必需的,但数据库最终被锁定。

但是,SQLite 是officially supported我觉得我搞砸了。

Flyway 如何与 SQLite 兼容?

最佳答案

使用类似于 Spring 的 SingleConnectionDataSource 的东西你应该很好。

更新:Flyway 4.1 现在在迁移时自动只使用一个连接,应该不再需要了。

关于java - 如何避免 Flyway Migrations 锁定 SQLite 数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30375308/

相关文章:

javascript - 如何从位于另一个文件中的查询函数获取结果? (Javascript、phoneGap 和 Sqlite)

java - 优雅地处理 SQL 空参数

java - 飞行路线集成到现有系统中

java - 更改密码时如何在 Java 客户端中收到 Active Directory 密码策略错误

java - Java 中的平坦地形生成

android - 将iOS coredata导入android sqlite

postgresql - 无法从 DataSource 获取 Jdbc 连接,SSL 错误 : Connection reset

docker - 错误 : Invalid argument: ./wait-for-it.sh

java - 如何使 DataOutputStream 将 boolean 值或整数写入 txt 文件?

java - 减少对象列表中的整数属性