Skip to content

[cloud_firestore] Transactions doesn't seem to work #54

Closed
@larssn

Description

@larssn

Issue moved from flutter/flutter#28714

So we're running into some issues with transactions, where update statements run without errors, except they don't always update the document in question. Below are a few simple tests.

Test 1

Setup
Run on two Android devices, and do a countdown to trigger the code at the same time. The code simulates an artificially long transaction execution, by using Future.delayed. One device will use Future.delayed(Duration(seconds: 3)); and the other will use Future.delayed(Duration(seconds: 2));. The default transaction timeout is 5 seconds, so we're well within that.

The write operation is incrementing a counter in a single document.
The document looks like so: { counter: 0 }.

try {
  final docRef = Firestore.instance.document('test/test-document');
  await Firestore.instance.runTransaction((Transaction tx) async {
    print('-- TRANSACTION START --');
    final postSnapshot = await tx.get(docRef);
    final newVal = 1 + postSnapshot['counter'];
    await Future.delayed(Duration(seconds: 3));
    print('Updating counter value ' + newVal.toString());
    await tx.update(postSnapshot.reference, {'counter': newVal});
    print('-- TRANSACTION END --');
  });
} catch (e) {
  print(e);
}

Results
Device 1 with 2 second transaction console output:

I/flutter (30734): -- TRANSACTION START --
I/flutter (30734): Updating counter value 1
I/flutter (30734): -- TRANSACTION END --

Device 2 with 3 second transaction console output:

I/flutter (12311): -- TRANSACTION START --
I/flutter (12311): Updating counter value 1
I/flutter (12311): -- TRANSACTION END --
I/flutter (12311): -- TRANSACTION START --
I/flutter (12311): Updating counter value 2
I/flutter (12311): -- TRANSACTION END --

Expected document value:
{ counter: 2 }
Actual document value:
{ counter: 1 }

Notes for Test 1:
From observing the logs, device 2 seems to do what it should: It restarts its transaction after it receives the updated document from device 1, but the value of 2 never makes it to the database.

Test 2

Setup
Identical to Test 1, except it's only run on a single device, and a timeout is introduced for the transaction, which is shorter than the execution time for the transaction.

try {
  await Firestore.instance.runTransaction((Transaction tx) async {
    // ... Identical to before
  }, timeout: Duration(seconds: 1)); // <-- HERE
} catch (e) {
  print(e);
}

Results
Actual console output:

I/flutter ( 1247): -- TRANSACTION START --
I/flutter ( 1247): PlatformException(Error performing transaction, Timed out waiting for Task, null)
I/flutter ( 1247): -- TRANSACTION START --
I/flutter ( 1247): Updating counter value 1
I/flutter ( 1247): -- TRANSACTION END --
I/flutter ( 1247): Updating counter value 1
I/flutter ( 1247): -- TRANSACTION END --

Expected console output:

I/flutter ( 1247): -- TRANSACTION START --
I/flutter ( 1247): PlatformException(Error performing transaction, Timed out waiting for Task, null)

Notes for Test 2:
I'm not expecting it to retry the transaction at all, since the catch handler has already output the error, meaning the transaction is done.

That's all for now. If we dream up some more tests that also cause unexpected results, we'll update this post.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions