Skip to content

Commit 5d605a1

Browse files
Initial sketch of manual commit
fix/add 'new in this edition' hints version history invert flag check don't let tx go inactive post-rebase cleanup
1 parent 59eeeb6 commit 5d605a1

File tree

1 file changed

+125
-17
lines changed

1 file changed

+125
-17
lines changed

index.bs

Lines changed: 125 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,8 @@ following:
934934
instead is created automatically when an
935935
<a event>`upgradeneeded`</a> event is fired.
936936

937+
A [=/transaction=] has an <dfn>manual commit flag</dfn>, which is initially false. By default, transactions commit automatically when all outstanding requests have been processed. This can be behavior can be modified by options set when creating the transaction.
938+
937939
A [=/transaction=] has a <dfn>durability hint</dfn>. This is a hint to the user agent of whether to prioritize performance or durability when committing the transaction. The [=transaction/durability hint=] is one of the following:
938940

939941
: {{"strict"}}
@@ -1041,10 +1043,11 @@ The <dfn>lifetime</dfn> of a
10411043
</aside>
10421044

10431045
1. When each [=/request=] associated with a transaction is [=request/processed=],
1044-
a <a event>`success`</a> or <a event>`error`</a> [=event=] will be
1045-
fired. While the event is being [=dispatched=], the transaction
1046+
a <a event>`success`</a> or <a event>`error`</a> [=event=] will be fired.
1047+
If the transaction's [=transaction/manual commit flag=] is false (the default), then
1048+
while the event is being [=dispatched=], the transaction
10461049
[=transaction/state=] is set to [=transaction/active=], allowing
1047-
additional requests to be made against the transaction. Once the
1050+
additional requests to be made against the transaction; once the
10481051
event dispatch is complete, the transaction's
10491052
[=transaction/state=] is set to [=transaction/inactive=] again.
10501053

@@ -1063,11 +1066,12 @@ The <dfn>lifetime</dfn> of a
10631066
[=/object stores=] as well as additions and removals of [=/object
10641067
stores=] and [=/indexes=].
10651068

1066-
1. The implementation must attempt to <dfn lt="commit|committed">commit</dfn>
1067-
a transaction when all [=/requests=] placed against the
1069+
1. If a transaction's [=transaction/manual commit flag=] is false, then
1070+
the implementation must attempt to <dfn lt="commit|committed">commit</dfn>
1071+
it when all [=/requests=] placed against the
10681072
transaction have completed and their returned results handled, no
10691073
new requests have been placed against the transaction, and the
1070-
transaction has not been [=transaction/aborted=]
1074+
transaction has not been [=transaction/aborted=].
10711075

10721076
An explicit call to {{IDBTransaction/commit()}} will initiate a
10731077
[=transaction/commit=] without waiting for request results to be
@@ -1104,7 +1108,7 @@ They will return true if any transactions were cleaned up, or false otherwise.
11041108
1. For each [=/transaction=] |transaction| with [=transaction/cleanup event loop=]
11051109
matching the current [=/event loop=]:
11061110

1107-
1. Set |transaction|'s [=transaction/state=] to [=transaction/inactive=].
1111+
1. If |transaction|'s [=transaction/manual commit flag=] is false, then set |transaction|'s [=transaction/state=] to [=transaction/inactive=].
11081112

11091113
1. Clear |transaction|'s [=transaction/cleanup event loop=].
11101114

@@ -1125,6 +1129,78 @@ a [=/transaction=] that has successfully [=transaction/committed=].
11251129
An event with type <dfn event>`abort`</dfn> is fired at
11261130
a [=/transaction=] that has [=transaction/aborted=].
11271131

1132+
1133+
<aside class=example id=example-transaction-autocommit>
1134+
1135+
The following example uses requests within a transaction to increment a counter value.
1136+
Event handlers log various state changes during the request and transaction lifecycles.
1137+
1138+
```js
1139+
const transaction = connection.transaction('my_data', 'readwrite');
1140+
const store = transaction.objectStore('my_data');
1141+
const get_request = store.get('counter');
1142+
get_request.onerror = e => {
1143+
console.warn(`get failed: ${get_request.error}`);
1144+
};
1145+
get_request.onsuccess = e => {
1146+
console.log(`get succeeded`);
1147+
const old_value = get_request.result;
1148+
const put_request = store.put(old_value + 1, 'counter');
1149+
put_request.onerror = e => {
1150+
console.warn(`get failed: ${put_request.error}`);
1151+
};
1152+
put_request.onsuccess = {
1153+
console.log(`put succeeded`);
1154+
// No more requests are made, so the transaction will autocommit.
1155+
};
1156+
};
1157+
1158+
transaction.onabort = e => {
1159+
console.warn(`transaction aborted: ${transaction.error}`);
1160+
};
1161+
1162+
transaction.oncomplete = e => {
1163+
console.log(`transaction committed`);
1164+
};
1165+
```
1166+
</aside>
1167+
1168+
<aside class=example id=example-transaction-manualcommit>
1169+
1170+
The following example uses requests within a transaction to atomically
1171+
update a record's value using an asynchronous network fetch. A manually
1172+
committing transaction is necessary.
1173+
1174+
```js
1175+
const transaction = connection.transaction(
1176+
'my_records, 'readwrite', {manualCommit: true});
1177+
1178+
const store = transaction.objectStore('my_records);
1179+
store.get('key').onsuccess = async e => {
1180+
try {
1181+
const record = e.target.result;
1182+
1183+
// Make an asynchronous network request. If the transaction
1184+
// was not set to manual commit, it would autocommit here
1185+
// because there were no outstanding requests.
1186+
const response = await fetch(record.url);
1187+
1188+
// Update the record.
1189+
record.status = response.status;
1190+
store.put(record, 'key');
1191+
1192+
// Commit the transaction, once the request has completed.
1193+
// If the request fails, the transaction will abort instead.
1194+
transaction.commit();
1195+
} catch (ex) {
1196+
// If the fetch() fails, abort the transaction.
1197+
transaction.abort();
1198+
}
1199+
});
1200+
```
1201+
</aside>
1202+
1203+
11281204
<!-- ============================================================ -->
11291205
### Transaction scheduling ### {#transaction-scheduling}
11301206
<!-- ============================================================ -->
@@ -2436,6 +2512,7 @@ interface IDBDatabase : EventTarget {
24362512
enum IDBTransactionDurability { "default", "strict", "relaxed" };
24372513

24382514
dictionary IDBTransactionOptions {
2515+
boolean manualCommit = false;
24392516
IDBTransactionDurability durability = "default";
24402517
};
24412518

@@ -2625,9 +2702,13 @@ instance on which it was called.
26252702
Returns a new [=/transaction=] with the given
26262703
|scope| (which can be a single [=/object store=] [=object-store/name=] or an array of [=object-store/names=]),
26272704
|mode| ({{"readonly"}} or {{"readwrite"}}),
2628-
and additional |options| including {{IDBTransactionOptions/durability}} ({{"default"}}, {{"strict"}} or {{"relaxed"}}).
2705+
and additional |options| including
2706+
{{IDBTransactionOptions/manualCommit}} (true or false), and
2707+
{{IDBTransactionOptions/durability}} ({{"default"}}, {{"strict"}} or {{"relaxed"}}).
26292708

2630-
The default |mode| is {{"readonly"}} and the default {{IDBTransactionOptions/durability}} is {{"default"}}.
2709+
The default |mode| is {{"readonly"}}.
2710+
The default {{IDBTransactionOptions/manualCommit}} is false.
2711+
The default {{IDBTransactionOptions/durability}} is {{"default"}}.
26312712

26322713
: |connection| . {{IDBDatabase/close()|close}}()
26332714
::
@@ -2658,7 +2739,11 @@ The <dfn method for=IDBDatabase>transaction(|storeNames|, |mode|, |options|)</df
26582739
1. If |mode| is not {{"readonly"}} or {{"readwrite"}},
26592740
[=throw=] a [=TypeError=].
26602741

2661-
1. Let |transaction| be a newly [=transaction/created=] [=/transaction=] with this [=/connection=], |mode|, |options|' {{IDBTransactionOptions/durability}} member, and the set of [=/object stores=] named in |scope|.
2742+
1. Let |transaction| be a newly [=transaction/created=] [=/transaction=] with this [=/connection=], |mode|, and the set of [=/object stores=] named in |scope|.
2743+
2744+
1. Set |transaction|'s [=transaction/manual commit flag=] to |options|' {{IDBTransactionOptions/manualCommit}} member.
2745+
2746+
1. Set |transaction|'s [=transaction/durability hint=] to |options|' {{IDBTransactionOptions/durability}} member.
26622747

26632748
1. Set |transaction|'s [=transaction/cleanup event loop=] to the
26642749
current [=/event loop=].
@@ -2667,6 +2752,12 @@ The <dfn method for=IDBDatabase>transaction(|storeNames|, |mode|, |options|)</df
26672752

26682753
</div>
26692754

2755+
<aside class=advisement>
2756+
&#x1F6A7;
2757+
The {{IDBTransactionOptions/manualCommit}} option is new in this edition.
2758+
&#x1F6A7;
2759+
</aside>
2760+
26702761
<aside class=advisement>
26712762
&#x1F6A7;
26722763
The {{IDBTransactionOptions/durability}} option is new in this edition.
@@ -4717,6 +4808,7 @@ the contents of the database.
47174808
interface IDBTransaction : EventTarget {
47184809
readonly attribute DOMStringList objectStoreNames;
47194810
readonly attribute IDBTransactionMode mode;
4811+
readonly attribute boolean manualCommit;
47204812
readonly attribute IDBTransactionDurability durability;
47214813
[SameObject] readonly attribute IDBDatabase db;
47224814
readonly attribute DOMException? error;
@@ -4751,6 +4843,10 @@ enum IDBTransactionMode {
47514843
({{"readonly"}} or {{"readwrite"}}), or {{"versionchange"}} for
47524844
an [=/upgrade transaction=].
47534845

4846+
: |transaction| . {{IDBTransaction/manualCommit}}
4847+
::
4848+
Returns true if the transaction was created with {{IDBTransactionOptions/manualCommit}}: `true` and false otherwise.
4849+
47544850
: |transaction| . {{IDBTransaction/durability}}
47554851
::
47564852
Returns the [=transaction/durability hint=] the transaction was created with
@@ -4791,6 +4887,14 @@ The <dfn attribute for=IDBTransaction>objectStoreNames</dfn> getter steps are:
47914887
The <dfn attribute for=IDBTransaction>mode</dfn> getter steps are to
47924888
return [=/this=]'s [=transaction/mode=].
47934889

4890+
The <dfn attribute for=IDBTransaction>manualCommit</dfn> attribute's getter must return [=/this=]'s [=transaction/manual commit flag=].
4891+
4892+
<aside class=advisement>
4893+
&#x1F6A7;
4894+
The {{IDBTransaction/manualCommit}} attribute is new in this edition.
4895+
&#x1F6A7;
4896+
</aside>
4897+
47944898
The <dfn attribute for=IDBTransaction>durability</dfn> getter steps are to return [=/this=]'s [=transaction/durability hint=].
47954899

47964900
<aside class=advisement>
@@ -4800,7 +4904,6 @@ The <dfn attribute for=IDBTransaction>durability</dfn> getter steps are to retur
48004904
&#x1F6A7;
48014905
</aside>
48024906

4803-
48044907
The <dfn attribute for=IDBTransaction>db</dfn> getter steps are to
48054908
return [=/this=]'s [=transaction/connection=]'s associated [=/database=].
48064909

@@ -4838,6 +4941,9 @@ none.
48384941
transaction to quickly finish, without waiting for pending requests to fire
48394942
<a event>`success`</a> events before attempting to commit normally.
48404943

4944+
If the transaction was created with `manualCommit: true` then this method
4945+
<span class=allow-2119>must</span> be called to commit the transaction.
4946+
48414947
The transaction will abort if a pending request fails, for example due to a
48424948
constraint error. The <a event>`success`</a> events for successful requests
48434949
will still fire, but throwing an exception in an event handler will not abort
@@ -4894,7 +5000,8 @@ The <dfn method for=IDBTransaction>abort()</dfn> method steps are:
48945000

48955001
The <dfn method for=IDBTransaction>commit()</dfn> method steps are:
48965002

4897-
1. If [=/this=]'s [=transaction/state=] is not [=transaction/active=],
5003+
1. If [=/this=]'s [=transaction/manual commit flag=] is false,
5004+
and [=/this=]'s [=transaction/state=] is not [=transaction/active=],
48985005
then [=throw=] an "{{InvalidStateError}}" {{DOMException}}.
48995006

49005007
1. Run [=commit a transaction=] with [=/this=].
@@ -5155,7 +5262,7 @@ To <dfn>commit a transaction</dfn> with the |transaction| to commit, run these s
51555262
<aside class=note>
51565263
Even if an exception is thrown from one of the event handlers of
51575264
this event, the transaction is still committed since writing the
5158-
database changes happens before the event takes places. Only
5265+
database changes happens before the event takes place. Only
51595266
after the transaction has been successfully written is the
51605267
<a event>`complete`</a> event fired.
51615268
</aside>
@@ -5484,14 +5591,14 @@ To <dfn>fire a success event</dfn> at a |request|, run these steps:
54845591
1. If |transaction|'s [=transaction/state=] is [=transaction/active=],
54855592
then:
54865593

5487-
1. Set |transaction|'s [=transaction/state=] to [=transaction/inactive=].
5594+
1. If |transaction|'s [=transaction/manual commit flag=] is false, then set |transaction|'s [=transaction/state=] to [=transaction/inactive=].
54885595

54895596
1. If |legacyOutputDidListenersThrowFlag| is true,
54905597
then run [=abort a transaction=] with
54915598
|transaction| and a newly <a for=exception>created</a>
54925599
"{{AbortError}}" {{DOMException}}.
54935600

5494-
1. If |transaction|'s [=transaction/request list=] is empty,
5601+
1. If |transaction|'s [=transaction/manual commit flag=] is false and if |transaction|'s [=transaction/request list=] is empty,
54955602
then run [=commit a transaction=] with |transaction|.
54965603

54975604
</div>
@@ -5523,7 +5630,7 @@ To <dfn>fire an error event</dfn> at a |request|, run these steps:
55235630
1. If |transaction|'s [=transaction/state=] is [=transaction/active=],
55245631
then:
55255632

5526-
1. Set |transaction|'s [=transaction/state=] to [=transaction/inactive=].
5633+
1. If |transaction|'s [=transaction/manual commit flag=] is false, then set |transaction|'s [=transaction/state=] to [=transaction/inactive=].
55275634

55285635
1. If |legacyOutputDidListenersThrowFlag| is true,
55295636
then run [=abort a transaction=] with
@@ -5544,7 +5651,7 @@ To <dfn>fire an error event</dfn> at a |request|, run these steps:
55445651
|transaction| and [=/request=]'s [=request/error=], and
55455652
terminate these steps.
55465653

5547-
1. If |transaction|'s [=transaction/request list=] is empty,
5654+
1. If |transaction|'s [=transaction/manual commit flag=] is false and |transaction|'s [=transaction/request list=] is empty,
55485655
then run [=commit a transaction=] with |transaction|.
55495656

55505657
</div>
@@ -6784,6 +6891,7 @@ For the revision history of the second edition, see [that document's Revision Hi
67846891
* Added {{IDBTransactionOptions/durability}} option and {{IDBTransaction/durability}} attribute. ([Issue #50](https://github.com/w3c/IndexedDB/issues/50))
67856892
* Specified [[#transaction-scheduling]] more precisely and disallow starting read/write transactions while read-only transactions with overlapping scope are running. ([Issue #253](https://github.com/w3c/IndexedDB/issues/253))
67866893
* Added <a href="#accessibility">Accessibility considerations</a> section. ([Issue #327](https://github.com/w3c/IndexedDB/issues/327))
6894+
* Specified [=transaction/manual commit flag=], {{IDBTransactionOptions/manualCommit}} option and {{IDBTransaction/manualCommit}} attribute. ([Issue #34](https://github.com/w3c/IndexedDB/issues/34))
67876895

67886896
<!-- ============================================================ -->
67896897
# Acknowledgements # {#acknowledgements}

0 commit comments

Comments
 (0)