mirror of https://github.com/AMT-Cheif/drift.git
Fix `computeWithDatabase` in transactions
This commit is contained in:
parent
54f6eea205
commit
3ee1c1ccd4
|
@ -3,6 +3,7 @@
|
|||
- Don't keep databases in an unusable state if the `setup` callback throws an
|
||||
exception. Instead, drift will retry the next time the database is used.
|
||||
- Allow targeting partial indices in `DoUpdate` ([#2394](https://github.com/simolus3/drift/issues/2394))
|
||||
- Fix deadlocks when `computeWithDatabase` is called inside a `transaction()`.
|
||||
|
||||
## 2.7.0
|
||||
|
||||
|
|
|
@ -221,13 +221,17 @@ extension ComputeWithDriftIsolate<DB extends DatabaseConnectionUser> on DB {
|
|||
/// requiring a database is also available through [computeWithDatabase].
|
||||
@experimental
|
||||
Future<DriftIsolate> serializableConnection() async {
|
||||
final currentlyInRootConnection = resolvedEngine is GeneratedDatabase;
|
||||
// ignore: invalid_use_of_protected_member
|
||||
final localConnection = connection;
|
||||
final localConnection = resolvedEngine.connection;
|
||||
final data = await localConnection.connectionData;
|
||||
|
||||
if (data is DriftIsolate) {
|
||||
// The local database is already connected to an isolate, use that one
|
||||
// directly.
|
||||
// If we're connected to an isolate already, we can use that one directly
|
||||
// instead of starting a short-lived drift server.
|
||||
// However, this does not work if [serializableConnection] is called in a
|
||||
// transaction zone, since the top-level connection could be blocked waiting
|
||||
// for the transaction (as transactions can't be concurrent in sqlite3).
|
||||
if (data is DriftIsolate && currentlyInRootConnection) {
|
||||
return data;
|
||||
} else {
|
||||
// Set up a drift server acting as a proxy to the existing database
|
||||
|
|
|
@ -199,6 +199,26 @@ void main() {
|
|||
// Make sure database still works after computeWithDatabase
|
||||
// https://github.com/simolus3/drift/issues/2279#issuecomment-1455385439
|
||||
await db.customSelect('SELECT 1').get();
|
||||
|
||||
// This should still work when computeWithDatabase is called in a
|
||||
// transaction.
|
||||
await db.transaction(() async {
|
||||
await db.into(db.categories).insert(
|
||||
CategoriesCompanion.insert(description: 'main / transaction'));
|
||||
|
||||
await db.computeWithDatabase(
|
||||
computation: (db) async {
|
||||
await db.batch((batch) {
|
||||
batch.insert(
|
||||
db.categories,
|
||||
CategoriesCompanion.insert(description: 'nested remote batch!'),
|
||||
);
|
||||
});
|
||||
},
|
||||
connect: TodoDb.new,
|
||||
);
|
||||
});
|
||||
|
||||
await db.close();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue