Skip to content

Commit c938b71

Browse files
DOC-9740 - Use refactored shared partials (#190)
https://issues.couchbase.com/browse/DOC-9740 [Page Preview](https://maria-robobug.github.io/DOC-9740/nodejs-sdk/DOC-9740/howtos/distributed-acid-transactions-from-the-sdk.html) * Use the changes made in [docs-sdk-common](couchbase/docs-sdk-common#45). * Included the `:page-toclevels: 2` attribute to improve UI (there are alot of sections in this doc, seems helpful for the user). * Added `acid-transactions-attributes.adoc` for SDK specific attributes (used by docs-sdk-common partials). Other SDKs to follow...
1 parent d81dc7e commit c938b71

File tree

3 files changed

+86
-45
lines changed

3 files changed

+86
-45
lines changed

modules/howtos/examples/transactions-example.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ async function main() {
6868
await cluster.transactions().run(async (ctx) => {
6969
// 'ctx' is a TransactionAttemptContext which permits getting, inserting,
7070
// removing and replacing documents, performing N1QL queries, etc.
71-
// … Your transction logic here …
71+
// … Your transaction logic here …
7272
// Committing is implicit at the end of the lambda.
7373
})
7474
} catch (error) {
@@ -320,8 +320,8 @@ async function queryInsert() {
320320
let collection = await getCollection()
321321
// tag::queryInsert[]
322322
cluster.transactions().run(async (ctx) => {
323-
ctx.query("INSERT INTO `default` VALUES ('doc', {'hello':'world'})")
324-
const st = "SELECT `default`.* FROM `default` WHERE META().id = 'doc'"
323+
ctx.query("INSERT INTO `default` VALUES ('doc', {'hello':'world'})") // <1>
324+
const st = "SELECT `default`.* FROM `default` WHERE META().id = 'doc'" // <2>
325325
const qr = await ctx.query(st)
326326
})
327327
// end::queryInsert[]

modules/howtos/pages/distributed-acid-transactions-from-the-sdk.adoc

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
:navtitle: ACID Transactions
44
:page-partial:
55
:page-topic-type: howto
6+
:page-toclevels: 2
67

78
include::project-docs:partial$attributes.adoc[]
9+
include::partial$acid-transactions-attributes.adoc[]
810

911
[abstract]
1012
{description}
@@ -37,30 +39,24 @@ include::example$transactions-example.ts[tag=config,indent=0]
3739

3840
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=config]
3941

40-
// TODO: this partial needs to change a bit, owing to library references.
4142
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=creating]
4243

4344
[source,typescript]
4445
----
4546
include::example$transactions-example.ts[tag=create,indent=0]
4647
----
4748

48-
// TODO: this partial may need to be reviewed
49-
// TODO: see https://docs.couchbase.com/java-sdk/current/howtos/distributed-acid-transactions-from-the-sdk.html#:~:text=The%20lambda%20gets%20passed%20an%20AttemptContext%20object%2C%20generally%20referred%20to%20as%20ctx%20here.
5049
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=lambda-ctx]
5150

52-
== Examples
53-
A code example is worth a thousand words, so here is a quick summary of the main transaction operations.
54-
They are described in more detail below.
51+
// Examples
52+
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=examples-intro]
5553

5654
[source,typescript]
5755
----
5856
include::example$transactions-example.ts[tag=examples,indent=0]
5957
----
6058

61-
// TODO: this partial references things that are Java implmentation specific
62-
// like a Transactions object
63-
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=mechanics]
59+
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tags=mechanics;!library-cleanup-process]
6460

6561

6662
== Key-Value Mutations
@@ -103,7 +99,7 @@ From a transaction context you may get a document:
10399
include::example$transactions-example.ts[tag=get,indent=0]
104100
----
105101

106-
`get` will cause the transaction to fail with `TransactionFailed` (after rolling back any changes, of course).
102+
`get` will cause the transaction to fail with `TransactionFailedError` (after rolling back any changes, of course).
107103
It is provided as a convenience method so the developer does not have to check the `Optional` if the document must exist for the transaction to succeed.
108104

109105
Gets will 'read your own writes', e.g. this will succeed:
@@ -113,15 +109,16 @@ Gets will 'read your own writes', e.g. this will succeed:
113109
include::example$transactions-example.ts[tag=getReadOwnWrites,indent=0]
114110
----
115111

116-
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=query-intro]
112+
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tags=query-intro;!library-begin-transaction]
117113

118114
=== Using N1QL
115+
119116
If you already use N1QL from the Node.js SDK, then its use in transactions is very similar.
120-
it returns the same `QueryResult` you are used to, and takes most of the same options.
117+
It returns the same `QueryResult` you are used to, and takes most of the same options.
121118

122119
You must take care to write `ctx.query()` inside the lambda however, rather than `cluster.query()` or `scope.query()`.
123120

124-
An example of SELECTing some rows from the `travel-sample` bucket:
121+
An example of selecting some rows from the `travel-sample` bucket:
125122

126123
[source,typescript]
127124
----
@@ -152,53 +149,63 @@ include::example$transactions-example.ts[tag=queryExamplesComplex,indent=0]
152149
----
153150

154151
=== Read Your Own Writes
152+
155153
As with Key-Value operations, N1QL queries support Read Your Own Writes.
156154

157-
This example shows INSERTing a document and then SELECTing it again.
155+
This example shows inserting a document and then selecting it again.
158156

159157
[source,typescript]
160158
----
161159
include::example$transactions-example.ts[tag=queryInsert,indent=0]
162160
----
161+
163162
<1> The inserted document is only staged at this point. as the transaction has not yet committed.
164163
Other transactions, and other non-transactional actors, will not be able to see this staged insert yet.
165164
<2> But the SELECT can, as we are reading a mutation staged inside the same transaction.
166165

167166
=== Mixing Key-Value and N1QL
167+
168168
Key-Value operations and queries can be freely intermixed, and will interact with each other as you would expect.
169169

170170
In this example we insert a document with Key-Value, and read it with a SELECT.
171+
171172
[source,typescript]
172173
----
173174
include::example$transactions-example.ts[tag=queryRyow,indent=0]
174175
----
176+
175177
<1> As with the 'Read Your Own Writes' example, here the insert is only staged, and so it is not visible to other transactions or non-transactional actors.
176178
<2> But the SELECT can view it, as the insert was in the same transaction.
177179

178180
=== Query Options
179-
Query options can be provided via `TransactionsQueryOptions`, which provides a subset of the options in the Node.js SDK's `QueryOptions`.
181+
182+
Query options can be provided via `TransactionQueryOptions`, which provides a subset of the options in the Node.js SDK's `QueryOptions`.
180183

181184
[source,typescript]
182185
----
183186
include::example$transactions-example.ts[tag=queryOptions,indent=0]
184187
----
185188

186-
// TODO: check this partial to see if it matches up across SDKs. otherwise, make it a table?
187-
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=query-options]
189+
The supported options are:
190+
191+
* parameters
192+
* scanConsistency
193+
* clientContextId
194+
* scanWait
195+
* scanCap
196+
* pipelineBatch
197+
* pipelineCap
198+
* profile
199+
* readOnly
200+
* adhoc
201+
* raw
188202

189203
// TODO: this does not seem to exist for Node.js. should it?
190204
//See the xref:howtos:n1ql-queries-with-sdk.adoc#query-options[QueryOptions documentation] for details on these.
205+
// Remove the API link below when we have the query options page available.
206+
See the https://docs.couchbase.com/sdk-api/couchbase-node-client/interfaces/TransactionQueryOptions.html[API reference] for more details on these.
191207

192-
// TODO: Replace the section below with this when we ensure that the shared partials in common are truly generic.
193-
// include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=query-perf]
194-
=== Query Performance Advice
195-
This section is optional reading, and only for those looking to maximize transactions performance.
196-
197-
After the first query statement in a transaction, subsequent Key-Value operations in the lambda are converted into N1QL and executed by the query service rather than the Key-Value data service.
198-
The operation will behave identically, and this implementation detail can largely be ignored, except for this caveat:
199-
200-
* These converted Key-Value operations are likely to be slightly slower, as the query service is optimised for statements involving multiple documents.
201-
Those looking for the maximum possible performance are recommended to put Key-Value operations before the first query in the lambda, if possible.
208+
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=query-perf]
202209

203210
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=query-single]
204211

@@ -207,6 +214,7 @@ include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=query-si
207214
include::example$transactions-example.ts[tag=querySingle,indent=0]
208215
----
209216

217+
// TODO: Add the below when this is implemented for Node.js transactions.
210218
// You can also run a single query transaction against a particular `Scope` (these examples will exclude the full error handling for brevity):
211219
//
212220
// [source,typescript]
@@ -240,16 +248,11 @@ An asynchronous cleanup process ensures that once the transaction reaches the co
240248
// == A Full Transaction Example
241249
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=example]
242250

243-
// TODO: need to create this
244-
// A complete version of this example is available on our https://github.com/couchbaselabs/couchbase-transactions-nodejs-examples[GitHub transactions examples page].
245-
246251
[source,typescript]
247252
----
248253
include::example$transactions-example.ts[tag=full,indent=0]
249254
----
250255

251-
// TODO: this partial has some Java specific things in it
252-
// concurrency
253256
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=concurrency]
254257

255258
// TODO: this is to identify violations of cooperative, not known if this is available in node/cb++
@@ -264,7 +267,7 @@ include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=concurre
264267

265268
== Rollback
266269

267-
If an exception is thrown, either by the application from the lambda, or by the transactions library, then that attempt is rolled back.
270+
If an exception is thrown, either by the application from the lambda, or by the transaction internally, then that attempt is rolled back.
268271
The transaction logic may or may not be retried, depending on the exception.
269272
//- see link:#error-handling[Error handling and logging].
270273

@@ -284,18 +287,21 @@ After a transaction is rolled back, it cannot be committed, no further operation
284287
// Error Handling
285288
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=error]
286289

290+
There are three errors that Couchbase transactions can raise to the application: `TransactionFailedError`, `TransactionExpiredError` and `TransactionCommitAmbiguousError`.
287291

288-
// TODO: this partial below has a lot of Java specifics in it
289-
// txnfailed
290-
//include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=txnfailed]
292+
// txnfailed
293+
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=txnfailed]
291294

295+
// TODO: Need an equivalent typescript snippet for the below
292296
//[source,java]
293297
//----
294298
//include::example$TransactionsExample.java[tag=config-expiration,indent=0]
295299
//----
296300
297-
//include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=txnfailed1]
301+
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=txnfailed1]
298302
303+
// TODO: Double check if this will be added in future.
304+
// Doesn't seem to be available for the Node SDK.
299305
//Similar to `TransactionResult`, `SingleQueryTransactionResult` also has an `unstagingComplete()` method.
300306
301307
=== Full Error Handling Example
@@ -307,14 +313,27 @@ Pulling all of the above together, this is the suggested best practice for error
307313
include::example$transactions-example.ts[tag=full-error-handling,indent=0]
308314
----
309315
310-
// TODO: this partial below has reference to a Transactions object, which is no longer the case going forward
311-
// include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=cleanup]
316+
// Asynchronous Cleanup
317+
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tags=cleanup;!library-cleanup-buckets]
318+
319+
[#tuning-cleanup]
320+
=== Configuring Cleanup
321+
322+
The cleanup settings can be configured as so:
323+
324+
[options="header"]
325+
|===
326+
|Setting|Default|Description
327+
|`cleanupWindow`|60 seconds|This determines how long a cleanup 'run' is; that is, how frequently this client will check its subset of ATR documents. It is perfectly valid for the application to change this setting, which is at a conservative default. Decreasing this will cause expiration transactions to be found more swiftly (generally, within this cleanup window), with the tradeoff of increasing the number of reads per second used for the scanning process.
328+
|`disableLostAttemptCleanup`|true|This is the thread that takes part in the distributed cleanup process described above, that cleans up expired transactions created by any client. It is strongly recommended that it is left enabled.
329+
|`disableClientAttemptCleanup`|true|This thread is for cleaning up transactions created just by this client. The client will preferentially aim to send any transactions it creates to this thread, leaving transactions for the distributed cleanup process only when it is forced to (for example, on an application crash). It is strongly recommended that it is left enabled.
330+
|===
312331
313332
=== Monitoring Cleanup
314333
315334
To monitor cleanup, increase the verbosity on the logging.
316335
317-
//TODO: once events are available, re-add the below
336+
//TODO: once events are available, re-add the below with relevant examples
318337
//[source,java]
319338
//----
320339
//include::example$TransactionsExample.java[tag=cleanup-events,indent=0]
@@ -380,7 +399,7 @@ There are two rules the application needs to follow:
380399
381400
* The first mutation must be performed alone, in serial.
382401
This is because the first mutation also triggers the creation of metadata for the transaction.
383-
* All concurrent operations must be allowed to complete fully, so the transaction library can track which operations need to be rolled back in the event of failure.
402+
* All concurrent operations must be allowed to complete fully, so the transaction can track which operations need to be rolled back in the event of failure.
384403
This means the application must 'swallow' the error, but record that an error occurred, and then at the end of the concurrent operations, if an error occurred, throw an error to cause the transaction to retry.
385404
386405
// TODO: update this for node
@@ -437,5 +456,4 @@ This means the application must 'swallow' the error, but record that an error oc
437456
//The transaction expiry timer (which is configurable) will begin ticking once the transaction starts, and is not paused while the transaction is in a deferred state.
438457
439458
440-
// TODO: this partial points to the java examples repo
441459
include::{version-server}@sdk:shared:partial$acid-transactions.adoc[tag=further]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// These attributes are used in sdk::shared:partial$acid-transactions.adoc
2+
3+
// intro
4+
:durability-exception: pass:q[`DurabilityImpossibleError`]
5+
6+
7+
// creating
8+
:lambda-attempt-ctx: pass:q[a `TransactionAttemptContext`]
9+
:collection-insert: pass:q[`collection.insert()`]
10+
:ctx-insert: pass:q[`ctx.insert()`]
11+
12+
13+
// error
14+
:ctx-get: pass:q[`ctx.get()`]
15+
:error-unstaging-complete: pass:q[`TransactionResult.unstagingComplete` property]
16+
17+
18+
// txnfailed
19+
:transaction-failed: TransactionFailedError
20+
:transaction-expired: TransactionExpiredError
21+
:transaction-config: TransactionsConfig
22+
:transaction-commit-ambiguous: TransactionCommitAmbiguous
23+
:txnfailed-unstaging-complete: TransactionResult.unstagingComplete

0 commit comments

Comments
 (0)