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

How to debug "database is locked" errors? #3378

Open
mrclauss opened this issue Dec 15, 2024 Discussed in #3343 · 4 comments
Open

How to debug "database is locked" errors? #3378

mrclauss opened this issue Dec 15, 2024 Discussed in #3343 · 4 comments

Comments

@mrclauss
Copy link

mrclauss commented Dec 15, 2024

Unfortunately my issue was not resolved by asserting only a single isolate accesses the database (see discussion below).

Observed with drift 2.21.0..

Stacktrace/Environment:
SqliteException(5): while executing statement, database is locked, database is locked (code 5) Causing statement: DELETE FROM "change_log_record_entry" WHERE "timestamp" < ?;, parameters: 1731832708

Stack trace:

package:sqlite3/src/implementation/exception.dart 75 throwException
package:sqlite3/src/implementation/statement.dart 109 StatementImplementation._execute
package:sqlite3/src/implementation/statement.dart 289 StatementImplementation.executeWith
package:sqlite3/src/statement.dart 79 CommonPreparedStatement.execute
package:drift/src/sqlite3/database.dart 149 Sqlite3Delegate.runWithArgsSync
package:drift/native.dart 392 _NativeDelegate.runUpdate.<fn>
dart:async/future.dart 313 new Future.sync
package:drift/native.dart 391 _NativeDelegate.runUpdate
package:drift/src/runtime/executor/helpers/engines.dart 96 _BaseExecutor.runDelete.<fn>
package:drift/src/runtime/executor/helpers/engines.dart 61 _BaseExecutor._synchronized
package:drift/src/runtime/executor/helpers/engines.dart 93 _BaseExecutor.runDelete
package:drift/src/runtime/api/connection.dart 102 DatabaseConnection.runDelete
package:drift/src/remote/server_impl.dart 158 ServerImplementation._runQuery
package:drift/src/remote/server_impl.dart 119 ServerImplementation._handleRequest.<fn>
package:drift/src/remote/communication.dart 165 DriftCommunication.setRequestHandler.<fn>
===== asynchronous gap ===========================
package:drift/src/remote/communication.dart 113 DriftCommunication.request
package:drift/src/remote/client_impl.dart 101 _BaseExecutor._runRequest
package:drift/src/remote/client_impl.dart 110 _BaseExecutor._intRequest
package:drift/src/remote/client_impl.dart 125 _BaseExecutor.runDelete
package:drift/src/utils/lazy_database.dart 77 LazyDatabase.runDelete
package:drift/src/runtime/api/connection.dart 102 DatabaseConnection.runDelete
package:drift/src/utils/lazy_database.dart 77 LazyDatabase.runDelete
package:drift/src/runtime/query_builder/statements/delete.dart 53 DeleteStatement.go.<fn>
package:drift/src/runtime/api/connection_user.dart 171 DatabaseConnectionUser.doWhenOpened.<fn>
dart:async/future_impl.dart 861 Future._propagateToListeners.handleValueCallback
dart:async/future_impl.dart 890 Future._propagateToListeners
dart:async/future_impl.dart 666 Future._completeWithValue
dart:async/future_impl.dart 736 Future._asyncCompleteWithValue.<fn>
dart:async/schedule_microtask.dart 40 _microtaskLoop
dart:async/schedule_microtask.dart 49 _startMicrotaskLoop

Device parameters:

id: AP4A.241205.013
board: lynx
bootloader: lynx-15.1-12292122
brand: google
device: lynx
display: AP4A.241205.013
fingerprint: google/lynx/lynx:15/AP4A.241205.013/12621605:user/release-keys
hardware: lynx
host: r-456ae1c9fa6a8c5c-nbp0
isPhysicalDevice: true
manufacturer: Google
model: Pixel 7a
product: lynx
tags: release-keys
type: user
versionBaseOs:
versionCodename: REL
versionIncremental: 12621605
versionPreviewSdk: 0
versionRelease: 15
versionSdk: 35
versionSecurityPatch: 2024-12-05

Application parameters:

environment: release
version: 3.0.0
appName: Contactulater
buildNumber: 153
packageName: es.com.skynet.contactulater

Discussed in #3343

Originally posted by mrclauss November 17, 2024
Hi folks, I do have a sporadic issue resulting in a SQLite "database is locked" error, however I'm not sure how to debug/resolve this. Are there any hints for solving this?

Drift version: "2.19.1+1"

Stacktrace looks like this:

SqliteException(5): while executing statement, database is locked, database is locked (code 5) Causing statement: UPDATE <.snipped.>, parameters: <.snipped.>

Stack trace:

package:sqlite3/src/implementation/exception.dart 75 throwException
package:sqlite3/src/implementation/statement.dart 109 StatementImplementation._execute
package:sqlite3/src/implementation/statement.dart 289 StatementImplementation.executeWith
package:sqlite3/src/statement.dart 79 CommonPreparedStatement.execute
package:drift/src/sqlite3/database.dart 149 Sqlite3Delegate.runWithArgsSync
package:drift/native.dart 340 _NativeDelegate.runUpdate.<fn>
dart:async/future.dart 313 new Future.sync
package:drift/native.dart 339 _NativeDelegate.runUpdate
package:drift/src/runtime/executor/helpers/engines.dart 96 _BaseExecutor.runDelete.<fn>
package:drift/src/runtime/executor/helpers/engines.dart 61 _BaseExecutor._synchronized
package:drift/src/runtime/executor/helpers/engines.dart 93 _BaseExecutor.runDelete
package:drift/src/runtime/api/connection.dart 102 DatabaseConnection.runDelete
package:drift/src/remote/server_impl.dart 153 ServerImplementation._runQuery
package:drift/src/remote/server_impl.dart 118 ServerImplementation._handleRequest.<fn>
package:drift/src/remote/communication.dart 165 DriftCommunication.setRequestHandler.<fn>
===== asynchronous gap ===========================
package:drift/src/remote/communication.dart 113 DriftCommunication.request
package:drift/src/remote/client_impl.dart 97 _BaseExecutor._runRequest
package:drift/src/remote/client_impl.dart 114 _BaseExecutor.runDelete
package:drift/src/utils/lazy_database.dart 91 LazyDatabase.runUpdate
package:drift/src/runtime/api/connection.dart 115 DatabaseConnection.runUpdate
package:drift/src/utils/lazy_database.dart 91 LazyDatabase.runUpdate
package:drift/src/runtime/query_builder/statements/update.dart 36 UpdateStatement._performQuery.<fn>
package:drift/src/runtime/api/connection_user.dart 171 DatabaseConnectionUser.doWhenOpened.<fn>
package:drift/src/runtime/query_builder/statements/update.dart 35 UpdateStatement._performQuery
package:drift/src/runtime/query_builder/statements/update.dart 158 UpdateStatement.replace
package:contactulater/db/userpropdao.dart 66 UserPropDao.update
package:contactulater/propertymanager.dart 781 PropertyManager.refreshDirtyNative.<fn>
package:synchronized/src/basic_lock.dart 36 BasicLock.synchronized

Any help appreciated :)

@simolus3
Copy link
Owner

Thanks for the follow-up! Unfortunately, these errors are not easy to debug since sqlite3 can't tell you which trace has originally obtained the lock.

Could you share how you're opening the database? If you're using driftDatabase() from package:drift_flutter, there's a new option that can make drift manage the isolates for you, automatically sharing them if a background / foreground service in the same Flutter engine are using the same database.

@mrclauss
Copy link
Author

mrclauss commented Dec 17, 2024

Previously I constructed it using openConnection, now I changed it to driftDatabase() from drift_flutter, but I can't find the option regarding isolates?

Here's the diff:

 class DriftDb extends _$DriftDb {
-  DriftDb() : super(openConnection());
+  DriftDb() : super(_openConnection());

+  static QueryExecutor _openConnection() {
+    // `driftDatabase` from `package:drift_flutter` stores the database in
+    // `getApplicationDocumentsDirectory()`.
+    return driftDatabase(name: 'db', );
+  }

@simolus3
Copy link
Owner

The option is nested under the native key: https://pub.dev/packages/drift_flutter#sharing-databases-between-isolates

@mrclauss
Copy link
Author

Thanks! Oddly that didn't appear in my Android Studio when I wrote the comment...
I'll give it a try now 👍

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

No branches or pull requests

2 participants