From 439f55374439a4d3b43a0f53735878093f2cc289 Mon Sep 17 00:00:00 2001 From: Elliot Scribner Date: Wed, 5 Jun 2024 14:45:13 -0700 Subject: [PATCH] DA-455: Refdoc Warning and Supporting Docs --- docusaurus/docs/advanced/transactions.md | 27 ++++++++++++++++++------ docusaurus/docs/basic/schema.md | 8 +++++-- src/ottoman/ottoman.ts | 6 ++++++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/docusaurus/docs/advanced/transactions.md b/docusaurus/docs/advanced/transactions.md index db36fd63..e9db2dc0 100644 --- a/docusaurus/docs/advanced/transactions.md +++ b/docusaurus/docs/advanced/transactions.md @@ -3,7 +3,7 @@ sidebar_position: 0 title: Transactions --- -A practical guide on using Couchbase Distributed ACID transactions. +A practical guide on using Couchbase Distributed ACID transactions in Ottoman. This guide will show you examples of how to perform multi-document ACID (atomic, consistent, isolated, and durable) database transactions within your application. @@ -11,7 +11,7 @@ database transactions within your application. Refer to the [Transaction Concepts](https://docs.couchbase.com/nodejs-sdk/current/concept-docs/transactions.html) concept page for a high-level overview. :::info Info -Ottoman's `transactions` implementation is intuitive and simple, if you already know how to use `Ottoman` you can start working with transactions in no time. +Ottoman's `transactions` implementation is intuitive and simple. If you already know how to use `Ottoman` you can start working with transactions in no time. If not, please check the basics: - [Ottoman](/docs/basic/ottoman) object @@ -53,7 +53,7 @@ If at any point an error occurs, the transaction will rollback and the arrow fun console.log(doc) ``` -The $transaction arrow function gets passed a `TransactionAttemptContext` object--generally referred to as `ctx` in these examples. +The `$transaction` arrow function gets passed a `TransactionAttemptContext` object--generally referred to as `ctx` in these examples. Since the arrow function could be rerun multiple times, it is important that it does not contain any side effects. In particular, you should never perform regular operations on a Collection, such as `create()` without using the `ctx`, inside the arrow function. Such operations may be performed multiple times, and will not be performed transactionally. @@ -107,8 +107,9 @@ this way the operation will know you intend to use it as a transaction, use it a ::: :::warning Pitfall -Not using the `{ transactionContext: ctx }` option inside the `$transaction` function will conduce to unexpected results. -Keep a sharp eye on it. +The **`{ transactionContext: ctx }` option _must_ be passed as a parameter when inside of a `$transaction` function**. Not passing this context will lead to unexpected results, and operations will not function as a transaction. + +Keep a sharp eye on it! ::: ### Rollback @@ -196,7 +197,7 @@ before continuing. This further increases safety, at the cost of additional late :::warning Caution A level of `None` is present but its use is discouraged and unsupported. -If durability is set to `None`, then ACID semantics are not guaranteed. +If durability is set to `None`, then ACID compliance is not guaranteed. ::: ### Ways of usage @@ -300,6 +301,20 @@ console.log(list); // the document shouldn't be created. ``` +### Transactions with RefDoc Indexes +:::danger Pitfall +**RefDoc Indexes are not currently supported with transactions.** Avoid accessing or mutating schemas that are indexed with a RefDoc index within a transaction. Doing so will lead to unexpected results, and operations will not function as a transaction. +::: +Any schema in your Ottoman project that is indexed with a [RefDoc index](/docs/basic/schema#refdoc) should **not be accessed or mutated within a transaction.** For example, if the `Swam` schema is indexed with a RefDoc index, the following code will work, but the transaction will not be atomic: +```typescript +await otttoman.$transactions(async (ctx: TransactionAttemptContext) => { + const odette = Swam.create({ name: 'Odette', age: 30 }, { transactionContext: ctx }); +}) +``` +It is acceptable to access _other_ schemas that are **not** indexed with a RefDoc index within a transaction. Ottoman will warn you if your project has **any** refdoc indexes when you attempt to use transactions, but it is up to you to ensure that you do not access or mutate these particular schemas within a transaction. + + + ### Additional Resources - Check the Couchbase Node.JS SDK [transaction documentation](https://docs.couchbase.com/nodejs-sdk/current/howtos/distributed-acid-transactions-from-the-sdk.html). diff --git a/docusaurus/docs/basic/schema.md b/docusaurus/docs/basic/schema.md index 9d9f8a44..6ef4bf1d 100644 --- a/docusaurus/docs/basic/schema.md +++ b/docusaurus/docs/basic/schema.md @@ -452,10 +452,14 @@ console.log(userRefdoc); } ``` +:::danger +**RefDoc Indexes** are not currently supported with transactions. If you plan to use transactions, see [Ottoman Transactions](/docs/advanced/transactions#transactions-with-refdoc-indexes) for more information. +::: + :::caution -**Refdoc Index** is not managed by Couchbase but strictly by Ottoman. It does not guarantee consistency if the keys that are a part of these indexes are updated by an external operation, like N1QL for example. +**RefDoc Index** is not managed by Couchbase but strictly by Ottoman. It does not guarantee consistency if the keys that are a part of these indexes are updated by an external operation, like N1QL for example. -**_Needs to be used with caution!!!_** +**_Please use with caution!_** ::: ### View diff --git a/src/ottoman/ottoman.ts b/src/ottoman/ottoman.ts index 590f301e..bd80274b 100644 --- a/src/ottoman/ottoman.ts +++ b/src/ottoman/ottoman.ts @@ -501,6 +501,12 @@ export class Ottoman { transactionFn: (attempt: TransactionAttemptContext) => Promise, config?: TransactionOptions, ) { + if (Object.keys(this.refdocIndexes).length > 0) { + console.warn( + '\x1b[4m\x1b[43mWARNING:\x1b[0m One or more RefDoc indexes have been detected in this project. RefDoc indexes are not currently supported in transactions. \nFor more information visit https://ottomanjs.com/docs/advanced/transactions#transactions-with-refdoc-indexes.', + ); + } + await this.cluster.transactions().run(transactionFn, config); } }