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
|
- 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.
|
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))
|
- 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
|
## 2.7.0
|
||||||
|
|
||||||
|
|
|
@ -221,13 +221,17 @@ extension ComputeWithDriftIsolate<DB extends DatabaseConnectionUser> on DB {
|
||||||
/// requiring a database is also available through [computeWithDatabase].
|
/// requiring a database is also available through [computeWithDatabase].
|
||||||
@experimental
|
@experimental
|
||||||
Future<DriftIsolate> serializableConnection() async {
|
Future<DriftIsolate> serializableConnection() async {
|
||||||
|
final currentlyInRootConnection = resolvedEngine is GeneratedDatabase;
|
||||||
// ignore: invalid_use_of_protected_member
|
// ignore: invalid_use_of_protected_member
|
||||||
final localConnection = connection;
|
final localConnection = resolvedEngine.connection;
|
||||||
final data = await localConnection.connectionData;
|
final data = await localConnection.connectionData;
|
||||||
|
|
||||||
if (data is DriftIsolate) {
|
// If we're connected to an isolate already, we can use that one directly
|
||||||
// The local database is already connected to an isolate, use that one
|
// instead of starting a short-lived drift server.
|
||||||
// directly.
|
// 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;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
// Set up a drift server acting as a proxy to the existing database
|
// 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
|
// Make sure database still works after computeWithDatabase
|
||||||
// https://github.com/simolus3/drift/issues/2279#issuecomment-1455385439
|
// https://github.com/simolus3/drift/issues/2279#issuecomment-1455385439
|
||||||
await db.customSelect('SELECT 1').get();
|
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();
|
await db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue