Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何避免Flyway迁移锁定SQLite数据库?_Java_Sqlite_Flyway - Fatal编程技术网

Java 如何避免Flyway迁移锁定SQLite数据库?

Java 如何避免Flyway迁移锁定SQLite数据库?,java,sqlite,flyway,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 o

我们使用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]
    ...
为什么?Flyway迁移似乎需要两个并行连接。 他们有一个相关的问题,并表示: “Flyway似乎至少使用了两个连接:一个用于锁定schema_version表,另一个用于实际运行alters…”


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

然而,SQLite是,我认为我搞砸了一些事情


Flyway如何能很好地与SQLite配合使用?

使用Spring之类的工具,你应该表现得很好


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

不幸的是,Flyway使用了两个到数据库的连接(一个用于元数据表,一个用于用户对象)。我不确定这是否是一个要求,但不管怎样,因为它需要两个连接,它不能被大小为1的标准连接池使用。此外,即使池中有2个连接,如果多个线程启动并使用Flyway,也有可能出现死锁。每个线程可能获得它所需的第一个连接,并无限期地阻塞等待第二个连接。实际上,我只是在我们的产品中提到了这一点,我们经常与Flyway交谈,以检查各种租户的模式版本。此问题适用于池的任何使用,并不特定于SQLite。

根据:“无法锁定”+此+“因为SQLite不支持锁定。不支持并发迁移。”);“并发迁移”意味着2个以上的应用程序在同一个数据库上运行迁移(另请参见),但这不是我们的用例。我在一次非并发迁移中成功地失败了。我还注意到flyway中的sqlite集成测试使用了一个memfile,因此它可能无法使用实际的文件。对于内存数据库(我出于好奇而进行了测试),迁移仍然挂起。但是这次使用的是表锁,而不是整个数据库锁。该测试配置了“共享缓存”,它允许SQLite连接共享相同的内存数据库。(然而,在此期间,Axel Fontaine对SingleConnectionDataSource解决方案的看法是正确的。)我也有同样的问题,但我不使用spring。在SQLite数据库上运行迁移还可以做些什么?SQLite的这种单连接方法现在内置于Flyway 4.1.0和更高版本中,根据:SQLite支持现在也基于新的单连接模式,避免了发布此信息后可能出现的各种锁定问题,我进一步挖掘了他们的源代码,发现他们在版本4.1中解决了这个问题。因此,如果您遇到这样的问题,请确保您使用的是4.1+更新:从Flyway 4.1.0及更高版本开始,根据:SQLite支持现在也基于新的单连接模式,避免了各种潜在的锁定问题
 ... 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)