Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java sqlite jdbc always database is locked #1120

Open
scf18857887860 opened this issue Jun 1, 2024 · 3 comments
Open

java sqlite jdbc always database is locked #1120

scf18857887860 opened this issue Jun 1, 2024 · 3 comments

Comments

@scf18857887860
Copy link

scf18857887860 commented Jun 1, 2024

Describe the bug
use HikariDataSource manage sqlite jdbc connection.

HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(url);
dataSource.setMaximumPoolSize(1);
dataSource.setMinimumIdle(1);
dataSource.setConnectionTimeout(50000);

but still happen database is locked.

To Reproduce
product enviroment is always happen. but test enviroment is less.

Expected behavior
A clear and concise description of what you expected to happen.

Logs

com.mybatisflex.core.transaction.TransactionException: null
	at com.mybatisflex.core.transaction.TransactionalManager.execNewTransactional(TransactionalManager.java:131)
	at com.mybatisflex.core.transaction.TransactionalManager.exec(TransactionalManager.java:69)
	at com.mybatisflex.core.row.Db.txWithResult(Db.java:1134)
	at com.mybatisflex.core.row.Db.txWithResult(Db.java:1127)
	at com.mes.dao.config.MecCommonTransactionManager.execTransaction(MecCommonTransactionManager.java:17)
	at com.mes.dao.dao.mysql.MysqlMESShopDataDao.setEx(MysqlMESShopDataDao.java:217)
	at com.mes.dao.dao.sqlite.SqliteMESShopDataDao.setEx(SqliteMESShopDataDao.java:83)
	at com.mes.thrift.ThriftServerCallbackImpl.isRepeatedMsg(ThriftServerCallbackImpl.java:256)
	at com.mes.thrift.ThriftServerCallbackImpl.Push(ThriftServerCallbackImpl.java:90)
	at com.maihui.platform.edge.messagecenter.ServerCallbackService$Processor$Push.getResult(ServerCallbackService.java:153)
	at com.maihui.platform.edge.messagecenter.ServerCallbackService$Processor$Push.getResult(ServerCallbackService.java:131)
	at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:40)
	at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:40)
	at com.mes.thrift.ThriftServerCallbackImpl.process(ThriftServerCallbackImpl.java:113)
	at com.mes.common.config.threadpoolutil.AESThreadPoolExecutor.lambda$execute$0(AESThreadPoolExecutor.java:35)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.UndeclaredThrowableException: null
	at com.sun.proxy.$Proxy13.insertSelective(Unknown Source)
	at com.mes.dao.config.BaseDao.create(BaseDao.java:48)
	at com.mes.dao.config.SynchronizedBaseDao.create(SynchronizedBaseDao.java:31)
	at com.mes.dao.dao.mysql.MysqlMESShopDataDao.newCache(MysqlMESShopDataDao.java:388)
	at com.mes.dao.dao.sqlite.SqliteMESShopDataDao.newCache(SqliteMESShopDataDao.java:118)
	at com.mes.dao.dao.mysql.MysqlMESShopDataDao.newCache(MysqlMESShopDataDao.java:368)
	at com.mes.dao.dao.sqlite.SqliteMESShopDataDao.newCache(SqliteMESShopDataDao.java:111)
	at com.mes.dao.dao.mysql.MysqlMESShopDataDao.lambda$setEx$3(MysqlMESShopDataDao.java:222)
	at com.mybatisflex.core.transaction.TransactionalManager.execNewTransactional(TransactionalManager.java:127)
	... 17 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.GeneratedMethodAccessor741.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.mybatisflex.core.mybatis.Mappers$MapperHandler.invoke(Mappers.java:110)
	... 26 common frames omitted
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: org.sqlite.SQLiteException: [SQLITE_BUSY_SNAPSHOT] Another database connection has already written to the database (database is locked)

Environment (please complete the following information):
windos 7
jdk 1.8

<dependency>
     <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.39.3.0</version>
</dependency>

Additional context
When my Java program performs database operations, I always add a global synchronized lock, but only for delete, insert, and update operations.

for example:

  synchronized (SynchronizedBaseDao.class) {
            return super.updateOrderStatus(orderKey, orderStatus, actionTime);
        }
@scf18857887860 scf18857887860 changed the title java sqlite java sqlite jdbc always database is locked Jun 1, 2024
@gotson
Copy link
Collaborator

gotson commented Jun 3, 2024

@scf18857887860
Copy link
Author

scf18857887860 commented Jun 3, 2024

did you check https://www.sqlite.org/rescode.html#busy_snapshot ?

thanks you i solve this problem,but happened a new problem

java.lang.reflect.UndeclaredThrowableException: null
	at com.sun.proxy.$Proxy23.close(Unknown Source)
	at com.mybatisflex.core.transaction.TransactionalManager.release(TransactionalManager.java:194)
	at com.mybatisflex.core.transaction.TransactionalManager.rollback(TransactionalManager.java:168)
	at com.mybatisflex.core.transaction.TransactionalManager.execNewTransactional(TransactionalManager.java:130)
	at com.mybatisflex.core.transaction.TransactionalManager.exec(TransactionalManager.java:69)
	at com.mybatisflex.core.row.Db.txWithResult(Db.java:1134)
	at com.mybatisflex.core.row.Db.txWithResult(Db.java:1127)
	at com.mes.dao.config.MecCommonTransactionManager.execTransaction(MecCommonTransactionManager.java:17)
	at com.mes.dao.dao.mysql.MysqlMESShopDataDao.expire(MysqlMESShopDataDao.java:189)
	at com.mes.dao.dao.sqlite.SqliteMESShopDataDao.expire(SqliteMESShopDataDao.java:69)
	at com.mes.thrift.ThriftServerCallbackImpl.isRepeatedMsg(ThriftServerCallbackImpl.java:255)
	at com.mes.thrift.ThriftServerCallbackImpl.Push(ThriftServerCallbackImpl.java:90)
	at com.maihui.platform.edge.messagecenter.ServerCallbackService$Processor$Push.getResult(ServerCallbackService.java:153)
	at com.maihui.platform.edge.messagecenter.ServerCallbackService$Processor$Push.getResult(ServerCallbackService.java:131)
	at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:40)
	at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:40)
	at com.mes.thrift.ThriftServerCallbackImpl.process(ThriftServerCallbackImpl.java:113)
	at com.mes.common.config.threadpoolutil.AESThreadPoolExecutor.lambda$execute$0(AESThreadPoolExecutor.java:35)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.GeneratedMethodAccessor291.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.mybatisflex.core.datasource.FlexDataSource$ConnectionHandler.invoke(FlexDataSource.java:263)
	... 21 common frames omitted
Caused by: java.sql.SQLException: database in auto-commit mode
	at org.sqlite.SQLiteConnection.rollback(SQLiteConnection.java:454)
	at com.zaxxer.hikari.pool.ProxyConnection.close(ProxyConnection.java:257)
	... 25 common frames omitted

i use HikariDataSource and set one connection

       HikariDataSource dataSource = new HikariDataSource();
            dataSource.setJdbcUrl(url);
            dataSource.setMaximumPoolSize(1);
            dataSource.setMinimumIdle(1);
            dataSource.setConnectionTimeout(50000);

@neoxpert
Copy link

neoxpert commented Aug 7, 2024

The "new" problem looks like a usage problem or issue within MyBatis' configuration.

By default all connections returned from a HikariDataSource have autoCommit be set to true (Doc). That is causing the shown stacktrace. Try and set the default value for autoCommit to false on the dataSource, or if you are passing connections around manually, you can just set the autoCommit to true on a certain connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants