次の方法で共有

存储过程、触发器和用户定义的函数

Azure Cosmos DB 提供 JavaScript 的语言集成事务执行。 在 Azure Cosmos DB 中使用 NoSQL API 时,可以使用 JavaScript 语言编写 存储过程触发器用户定义的函数(UDF )。 可以在 JavaScript 中编写逻辑,该逻辑在数据库引擎内执行。 可以使用 Azure 门户Azure Cosmos DB 中的 JavaScript 语言集成查询 API用于 NoSQL 客户端 SDK 的 Azure Cosmos DB 创建和执行触发器、存储过程和 UDF。

使用服务器端编程的好处

在 JavaScript 中编写存储过程、触发器和用户定义的函数(UDF)可让你生成丰富的应用程序,并且它们具有以下优势:

  • 过程逻辑: JavaScript 是一种高级编程语言,提供丰富的熟悉界面来表达业务逻辑。 可以对数据执行一系列复杂操作。

  • 原子事务: 在单个存储过程或触发器中执行的 Azure Cosmos DB 数据库操作是原子的。 此原子功能允许应用程序将相关操作合并到单个批处理中,以便所有操作都成功或其中一个都不成功。

  • 性能:JSON 数据本质上与 JavaScript 语言类型系统相对应。 此映射允许多种优化,例如在缓冲池中按需实例化 JSON 文档,并按需提供给运行代码。 还有其他与将业务逻辑转移到数据库相关的性能优势,其中包括:

    • 批处理: 你可以将插入等操作进行分组,并批量提交。 网络流量延迟成本和为创建单独事务所需的存储开销显著减少。

    • 预编译: 存储过程、触发器和 UDF 隐式预编译为字节代码格式,以避免每次脚本调用时编译成本。 由于预编译,存储过程的调用速度很快,占用空间较低。

    • 测 序: 有时,作需要触发机制,该机制可能会对数据执行一个或多个其他更新。 除了 Atomicity 之外,在服务器端执行时也有性能优势。

  • 封装: 存储过程可用于将逻辑分组到一个位置。 封装在数据之上添加一个抽象层,使你可以独立于数据发展应用程序。 当数据无架构且无需管理直接在应用程序中添加其他逻辑时,这种抽象层非常有用。 通过抽象,可以通过简化脚本的访问来保护数据。

小窍门

存储过程最适合执行写入密集型操作,并且需要跨分区键值进行事务处理。 在决定是否使用存储过程时,请围绕封装可能的最大写入量进行优化。 一般来说,存储过程不是执行大量读取或查询作的最有效手段,因此使用存储过程批处理大量读取以返回到客户端不会产生所需的好处。 为了获得最佳性能,应使用 Azure Cosmos DB SDK 在客户端执行这些读取密集型作。

建议不要使用具有强一致性的存储过程,因为突变是局部的。

注释

服务器端 JavaScript 功能(包括存储过程、触发器和用户定义的函数)不支持导入模块。

Transactions

典型数据库中的事务可以定义为作为单个逻辑工作单元执行的作序列。 每个事务都提供 ACID 属性保证。 ACID 是一个众所周知的首字母缩略词,代表:原子性一致性隔离性持久性

  • “原子性”保证将一个事务内部执行的所有操作视为一个单位,这些操作要么全部提交,要么都不提交。

  • 一致性确保数据始终在各个事务之间处于有效状态。

  • 隔离 保证两个事务不会相互干扰 - 许多商业系统提供多个隔离级别,这些隔离级别可以根据应用程序的需求使用。

  • 持久性 可确保数据库中提交的任何更改始终存在。

在 Azure Cosmos DB 中,JavaScript 运行时托管在数据库引擎内。 因此,在存储过程内发出的请求和触发器在数据库会话所在的同一范围内执行。 此功能使 Azure Cosmos DB 能够保证存储过程或触发器中的每个操作的 ACID 特性。 有关示例,请参阅 如何实现事务 文章。

小窍门

对于 Azure Cosmos DB for NoSQL 中的事务支持,还可以使用首选客户端 SDK 实现事务批处理。 有关详细信息,请参阅 Azure Cosmos DB for NoSQL 中的事务批处理作

事务的范围

存储过程与 Azure Cosmos DB 容器相关联,存储过程执行的范围限定为逻辑分区键。 存储过程必须在执行期间包含逻辑分区键值,该值定义事务范围的逻辑分区。 有关详细信息,请参阅 Azure Cosmos DB 分区 文章。

提交和回滚

事务本机集成到 Azure Cosmos DB JavaScript 编程模型中。 在 JavaScript 函数中,所有操作都自动封装在单个事务中。 如果存储过程中的 JavaScript 逻辑完成且未发生任何异常,则事务中的所有操作会被提交到数据库。 在 Azure Cosmos DB 中,类似于关系数据库的语句 BEGIN TRANSACTIONCOMMIT TRANSACTION 是隐含的。 如果脚本存在任何异常,Azure Cosmos DB JavaScript 运行时将回滚整个事务。 因此,引发异常实际上等效于在 Azure Cosmos DB 中的ROLLBACK TRANSACTION

数据一致性

存储过程和触发器始终在 Azure Cosmos DB 容器的主副本上执行。 此功能可确保从存储过程读取提供 强一致性。 可以使用用户定义的函数对主要副本或任何次要副本执行查询。 存储过程和触发器旨在支持事务写入。 同时,只读逻辑最好是使用 适用于 NoSQL SDK 的 Azure Cosmos DB 作为应用程序端逻辑和查询实现的,这有助于使数据库吞吐量饱和。

小窍门

在存储过程或触发器中执行的查询可能不会反映由同一个脚本事务所做的对项目的更改。 此语句适用于 SQL 查询,例如 getContent().getCollection().queryDocuments(),以及集成语言查询,例如 getContext().getCollection().filter()

有限执行

所有 Azure Cosmos DB 操作都必须在指定的超时时间内完成。 存储过程的超时限制为 5 秒。 此约束适用于 JavaScript 函数 - 存储过程、触发器和用户定义的函数。 如果某个操作在该时间限制内未完成,则会回滚该事务。

可以确保 JavaScript 函数在时间限制内完成,或实现基于延续的模型以批处理/恢复执行。 为了简化存储过程和触发器的开发以处理时间限制,Azure Cosmos DB 容器下的所有函数(例如,创建、读取、更新和删除项)返回一个布尔值,该值表示该作是否完成。 如果此值为 false,则表明该过程必须结束执行,因为脚本消耗的时间或预配的吞吐量超过配置的值。 如果存储过程按时完成并且不排队更多请求,则保证在第一个未被接受的存储操作之前排队的操作完成。 因此,应使用 JavaScript 回调机制依次排队操作,以管理脚本的控制流。 由于脚本在服务器端环境中执行,因此会严格控制这些脚本。 重复违反执行边界的脚本可能标记为非活动且无法执行,并且应重新创建它们以遵守执行边界。

JavaScript 函数还受 预配吞吐量容量的约束。 JavaScript 函数可能最终在短时间内使用大量请求单位,如果达到预配的吞吐量容量限制,可能会受到限制。 请务必注意,除了执行数据库作所用的吞吐量外,脚本还会消耗额外的吞吐量,尽管这些数据库作的成本略低于从客户端执行的相同作。

Triggers

Azure Cosmos DB 支持两种类型的触发器:

预触发器

Azure Cosmos DB 提供可以通过对 Azure Cosmos DB 项执行作来调用的触发器。 例如,可以在创建项时指定预触发器。 在这种情况下,预触发器将在创建项之前运行。 预触发器不能有任何输入参数。 如有必要,可以使用请求对象从原始请求更新文档正文。 注册触发器时,用户可以指定它可以运行的操作。 如果创建了 TriggerOperation.Create触发器,这意味着不允许在替换操作中使用该触发器。 有关示例,请参阅 如何编写触发器 文章。

后置触发器

与前触发器类似,后触发器也与 Azure Cosmos DB 项目上的一个操作相关联,并且不需要任何输入参数。 在操作完成后运行,并可以访问发送到客户端的响应消息。 有关示例,请参阅 如何编写触发器 文章。

注释

注册的触发器在其相应的操作(创建/删除/替换/更新)发生时不会自动运行。 在执行这些操作时必须显式调用它们。 若要了解详细信息,请参阅 如何运行触发器 文章。

用户定义的函数

用户定义的函数(UDF)用于扩展 API for NoSQL 查询语言语法并轻松实现自定义业务逻辑。 只能在查询中调用它们。 UDF 无权访问上下文对象,旨在用作仅计算 JavaScript。 因此,UDF 可以在次要副本上运行。

JavaScript 语言集成查询 API

除了使用 API for NoSQL 查询语法发出查询外, 服务器端 SDK 还允许使用 JavaScript 接口执行查询,而无需了解 SQL。 JavaScript 查询 API 允许通过将谓词函数传递到函数调用序列,以编程方式生成查询。 查询由 JavaScript 运行时进行分析,并在 Azure Cosmos DB 中高效执行。 若要了解 JavaScript 查询 API 支持,请参阅 使用 JavaScript 语言集成查询 API 一文。 有关示例,请参阅 如何使用 JavaScript 查询 API 一文编写存储过程和触发器

后续步骤

使用以下文章了解如何在 Azure Cosmos DB 中编写和使用存储过程、触发器和用户定义的函数:

尝试为迁移到 Azure Cosmos DB 进行容量规划? 可以使用有关现有数据库群集的信息进行容量规划。