WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED DUPLICATE of
bug 216769
222746
IDBTransaction is closed prematurely if a microtask is awaited after opening the transaction under some circumstances
https://bugs.webkit.org/show_bug.cgi?id=222746
Summary
IDBTransaction is closed prematurely if a microtask is awaited after opening ...
Bruno Windels
Reported
2021-03-04 09:49:27 PST
Created
attachment 422245
[details]
a small test case reproducing the problem I'm encountering an issue with IndexedDB which I can reproduce on several webkit based browsers (Safari on iOS 13.4, Safari TP 121 on macOS 10.15, and WebKitGTK 2.30.5 on Linux). The issue is that under some circumstances, an IDBTransaction can get closed if you wait a single microtask (e.g. await Promise.resolve()) to queue your first IDBRequest (as opposed to a macrotask, which is expected). In the web app where I encountered the issue, it happens easily if I have optional async code path after opening a transaction (async because they use indexeddb, no other macro tasks). I've attached a test case that reproduces the problem, where scheduling a macro task in between two transactions seems to trigger the bug. I have reduced it as much as possible, so every step is essential to reproduce the problem AFAIK.
Attachments
a small test case reproducing the problem
(2.49 KB, text/html)
2021-03-04 09:49 PST
,
Bruno Windels
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Chris Dumez
Comment 1
2021-03-08 10:09:11 PST
The IDBTransaction constructor uses this: vm.whenIdle([protectedThis = makeRef(*this)]() { protectedThis->deactivate(); }); It seems our lambda is getting called prematurely here because the JS is using await on a setTimeout.
Sihui Liu
Comment 2
2021-03-08 10:35:30 PST
Seem the same as
https://bugs.webkit.org/show_bug.cgi?id=216769
Chris Dumez
Comment 3
2021-03-08 11:00:35 PST
Interesting part of the repro case: ``` try { const db = await openDatabase(dbName, db => { db.createObjectStore("test", {keyPath: "key"}); }, 1); const readTxn = db.transaction(["test"], "readonly"); await reqAsPromise(readTxn.objectStore("test").get("somekey")); // schedule a macro task in between the two txns await new Promise(r => setTimeout(r, 0)); const writeTxn = db.transaction(["test"], "readwrite"); await Promise.resolve(); writeTxn.objectStore("test").add({key: "somekey", value: "foo"}); await txnAsPromise(writeTxn); } catch (err) { if (err.name === "TransactionInactiveError") { return true; // BUG } ``` So it looks like whenIdle called our lambda before the call to: writeTxn.objectStore("test").add() Calling our lambda deactivated the writeTxn, which is why we reject the promise with a TransactionInactiveError.
Radar WebKit Bug Importer
Comment 4
2021-03-11 09:50:15 PST
<
rdar://problem/75320436
>
Sihui Liu
Comment 5
2021-03-11 10:30:09 PST
*** This bug has been marked as a duplicate of
bug 216769
***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug