diff --git a/docs/uniCloud/_sidebar.md b/docs/uniCloud/_sidebar.md index cd49aba09f0e62e3f5757f8e25e937d78d088e44..b96b48132d191009371dd7df432e131a41ddfda6 100644 --- a/docs/uniCloud/_sidebar.md +++ b/docs/uniCloud/_sidebar.md @@ -9,10 +9,10 @@ * [日志输出](uniCloud/cf-logger.md) * [身份认证](uniCloud/cf-authentication.md) * [定时触发](uniCloud/trigger.md) - * [HTTP触发](uniCloud/http.md) + * [设置HTTP访问地址](uniCloud/http.md) * [云数据库](uniCloud/cf-database.md) * [云存储](uniCloud/storage.md) -* [登录授权](uniCloud/authentication.md) +* [云Token](uniCloud/authentication.md) * 权限管理 * [腾讯云](uniCloud/policy-tcb.md) diff --git a/docs/uniCloud/cf-database.md b/docs/uniCloud/cf-database.md index 3592216991fb75e41f580219b6dd0e7c98d63ffb..19ba934306bbd149528685dd349f87fa4f3b7b17 100644 --- a/docs/uniCloud/cf-database.md +++ b/docs/uniCloud/cf-database.md @@ -1198,6 +1198,181 @@ db.collection('user').where({ ``` --> +## 事务 + +**目前仅腾讯云支持事务,阿里云暂不支持** + +事务通常用来在某个数据库操作失败之后进行回滚。 + +### runTransaction + +发起事务。与`startTransaction`作用类似,接收参数类型不同 + +**`runTransaction` 的形式如下:** + +```javascript +db.runTransaction(callback: function, times: number) +``` + +**参数** + +|参数 |类型 |说明 | +|--- |--- |--- | +|callback |Function |事务执行函数,需为 async 异步函数或返回 Promise 的函数 | +|times |Number |事务执行最多次数,默认 3 次,成功后不重复执行,只有事务冲突时会重试,其他异常时不会重试| + +**返回值** + +`runTransaction`返回一个`Promise`,此`Promise.resolve`的结果为`callback`事务执行函数的返回值,`reject` 的结果为事务执行过程中抛出的异常或者是 `transaction.rollback` 传入的值 + +**callback 事务执行函数的说明** + +事务执行函数由开发者传入,函数接收一个参数 transaction,其上提供 collection 方法和 rollback 方法。collection 方法用于取数据库集合记录引用进行操作,rollback 方法用于在不想继续执行事务时终止并回滚事务。 + +事务执行函数必须为 `async` 异步函数或返回 `Promise` 的函数,当事务执行函数返回时,uniCloud 会认为用户逻辑已完成,自动提交(`commit`)事务,因此务必确保用户事务逻辑完成后才在 `async` 异步函数中返回或 `resolve Promise`。 + +事务执行函数可能会被执行多次,在内部发现事务冲突时会自动重复执行,如果超过设定的执行次数上限,会报错退出。 + +在事务执行函数中发生的错误,都会认为事务执行失败而抛错。 + +事务执行函数返回的值会作为 `runTransaction` 返回的 `Promise resolve` 的值,在函数中抛出的异常会作为 `runTransaction` 返回的 `Promise reject` 的值,如果事务执行函数中调用了 `transaction.rollback`,则传入 `rollback` 函数的值会作为 `runTransaction` 返回的 `Promise reject` 的值。 + +**限制** + +事务操作时为保障效率和并发性,只允许进行单记录操作,不允许进行批量操作,但可以在一个事务进行多次数据库操作。 + +**注意事项** + +开发者提供的事务执行函数正常返回时,uniCloud 会自动提交(`commit`)事务,请勿在事务执行函数内调用 `transaction.commit` 方法,该方法仅在通过 `db.startTransaction` 进行事务操作时使用 + +**示例代码** + +两个账户之间进行转账的简易示例 + +```javascript +const db = uniCloud.database() +const _ = db.command +exports.main = async (event) => { + try { + const result = await db.runTransaction(async transaction => { + const aaaRes = await transaction.collection('account').doc('aaa').get() + const bbbRes = await transaction.collection('account').doc('bbb').get() + + if (aaaRes.data && bbbRes.data) { + const updateAAARes = await transaction.collection('account').doc('aaa').update({ + data: { + amount: _.inc(-10) + } + }) + + const updateBBBRes = await transaction.collection('account').doc('bbb').update({ + data: { + amount: _.inc(10) + } + }) + + console.log(`transaction succeeded`) + + // 会作为 runTransaction resolve 的结果返回 + return { + aaaAccount: aaaRes.data.amount - 10, + } + } else { + // 会作为 runTransaction reject 的结果出去 + await transaction.rollback(-100) + } + }) + + return { + success: true, + aaaAccount: result.aaaAccount, + } + } catch (e) { + console.error(`transaction error`, e) + + return { + success: false, + error: e + } + } +} +``` + +### startTransaction + +发起事务。与`runTransaction`作用类似,接收参数类型不同 + +**`startTransaction` 形式如下** + +```javascript +// 与runTransaction不同,startTransaction不接收参数 +db.startTransaction() +``` + +**返回值** + +返回一个`Promise`,此`Promise resolve`的结果为事务操作对象(**注意这里与runTransaction的区别**),其上可通过 `collection API` 操作数据库,通过 `commit`(**使用`startTransaction`需要主动`commit`**) 或 `rollback` 来结束或终止事务。 + +**限制** + +事务操作时为保障效率和并发性,只允许进行单记录操作,不允许进行批量操作,但可以在一个事务进行多次数据库操作。 + +**示例代码** + +两个账户之间进行转账的简易示例 + +```javascript +const db = uniCloud.database() +const _ = db.command + +exports.main = async (event) => { + try { + const transaction = await db.startTransaction() + + const aaaRes = await transaction.collection('account').doc('aaa').get() + const bbbRes = await transaction.collection('account').doc('bbb').get() + + if (aaaRes.data && bbbRes.data) { + const updateAAARes = await transaction.collection('account').doc('aaa').update({ + data: { + amount: _.inc(-10) + } + }) + + const updateBBBRes = await transaction.collection('account').doc('bbb').update({ + data: { + amount: _.inc(10) + } + }) + + await transaction.commit() + + console.log(`transaction succeeded`) + + return { + success: true, + aaaAccount: aaaRes.data.amount - 10, + } + } else { + await transaction.rollback() + + return { + success: false, + error: `rollback`, + rollbackCode: -100, + } + } + } catch (e) { + console.error(`transaction error`, e) + + return { + success: false, + error: e + } + } +} +``` + ## 聚合操作 获取数据库集合的聚合操作实例 diff --git a/docs/uniCloud/http.md b/docs/uniCloud/http.md index 13ed565ad9c212a39de7c4065ef09e3cd0407846..9b7b7c6597a611220aaaa608e8bce8aa793dc570 100644 --- a/docs/uniCloud/http.md +++ b/docs/uniCloud/http.md @@ -2,18 +2,18 @@ ## 操作场景 -HTTP 触发是云开发为开发者提供的 HTTP 访问服务,让开发者可以通过 HTTP 访问到自己的云开发资源。 +设置HTTP访问地址 是 uniCloud 为开发者提供的 HTTP 访问服务,让开发者可以通过 HTTP 访问到自己的云函数。 - 当开启某一函数的 HTTP 访问后,只要根据 HTTP 即可访问到函数,开发者需要关注业务和资源安全。 - 安全:为了保障业务安全性,开发者需在代码中做好权限控制和安全防护,避免未授权访问触发敏感操作。 -- 计费:云函数开启了 HTTP 访问后,如果遇到大量恶意访问,消耗云函数资源,开发者可以将触发路径设置为空或关掉该服务空间的 HTTP 触发,停止 HTTP 访问支持。 +- 计费:云函数开启了 HTTP 访问后,如果遇到大量恶意访问,消耗云函数资源,开发者可以将云函数访问地址设置为空即可停止 HTTP 访问支持。 本文档主要指导您如何在uniCloud web控制台管理和使用云函数 HTTP 访问。 ## 操作步骤 -### 设置云函数 HTTP 触发路径 +### 设置云函数 HTTP 访问地址 1. 登录[uniCloud后台](https://unicloud.dcloud.net.cn/),选择需要管理的服务空间。 2. 单击左侧菜单栏【云函数】,进入云函数页面。 @@ -27,9 +27,9 @@ HTTP 触发是云开发为开发者提供的 HTTP 访问服务,让开发者可 2. 单击【HTTP 触发】,在 HTTP 触发配置窗口中进行配置。 ![](https://main.qcloudimg.com/raw/d57783a65d625708f45f628eddbe9139.jpg) >! ->- 每个服务空间最多绑定5个自定义域名。 +>- 每个服务空间最多绑定1个自定义域名。 >- 云开发提供默认域名供体验和测试该特性,域名规范如:`${spaceId}.service.tcloudbase.com`。 ->- 绑定自定义域名之前,请先设置您默认域名的 CNAME 记录值为`${spaceId}.service.tcloudbase.com`,CNAME 记录不存在时会导致域名绑定失。 +>- 绑定自定义域名之前,请先设置您默认域名的 CNAME 记录值为`${spaceId}.service.tcloudbase.com`,CNAME 记录不存在时会导致域名绑定失败。 >- 单个服务空间可支持被访问的最大 QPS 为5000,单个云函数可支持被访问的最大 QPS 为2000(具体频次受函数并发限制)。 >- 默认域名可支持被访问的最大 QPS 为200,推荐您绑定自定义域名以获取更大的访问频次。