跳到正文
豫言包管理
← 全部包

豫言操作系统持久事务 0.2.0

豫言 · 库

在同一持久仓原子读取、写入、删除、列举并返回结构化值,也可在普通持久对象事件中直接访问持久仓。

持久事务接口规范 0.2.0

本包让应用读写当前持久对象(Durable Object)的持久仓,并在同一个原子事务里做多步读写。0.2.0 在 0.1.0 之上只增函数,旧函数签名不变:补足事务内的删除、列举与回滚,并让应用在普通持久对象事件(durable-fetch、durable-alarm、套接字事件等)里直接读写持久仓。仓内每个键的值是一个 JSON 值:宿主以结构化值存入平台存储,因此与既有 JavaScript 对象写入的数据互通——读出时得到该值的 JSON 文字,应用写入 JSON 文字后,旧 JavaScript 代码读到的是同一个对象。仓由当前持久对象独占,宿主不得把另一个对象、另一次事务的状态暴露给调用方。

事务

执行持久事务 接受有效 JSON 文字,在同一仓内调用应用的事务处理入口(事件种类 durable-transaction,应用据[网页入站接口](../网页入站/规范.汉语.md)的事件种类选择处理入口),成功时返回入口设定的 JSON 结果文字。处理入口通过 读取持久事务参数 取得本次参数;通过 读取持久事务键值、写入持久事务键值、删除持久事务键、列举持久事务键值 读写当前事务的键;通过 回滚持久事务 放弃本事务已作的全部写入;完成持久事务 每次事务必须且只能成功调用一次。输入 JSON 由宿主验证,输出须为有效 JSON。

所有读写属于同一个原子事务:处理入口抛错、缺少结果、超时或存储失败时,已写入的键、已设置或删除的告警都不得提交。一个仓内并发事务串行执行,且事务处理入口运行期间宿主不向该对象投递其他事件(它们排队等候,等价于[持久独占](../持久独占/规范.汉语.md)),所以事务里可以等待外部输入输出,但应尽量短:平台在事务回调超过 30 秒时会重置整个对象,宿主因而把 durable-transaction 事件默认限制在 25 秒内(可配置,不得超过 30 秒),超时表现为 执行持久事务 抛出的可捕获异常。回滚持久事务 之后不得再读写本事务的键(平台会拒绝这些调用),处理入口应立即 完成持久事务。事务处理入口内不能再启动事务或[持久独占](../持久独占/规范.汉语.md)区;在事务处理入口里调用[持久告警](../持久告警/规范.汉语.md)函数时,告警的设置与删除与本事务同命运(事务提交则生效,回滚或失败则撤销)。

执行持久事务 失败时(处理入口抛出未捕获异常、没有调用 完成持久事务、结果不是有效 JSON、事务超时、存储失败)抛出可用「尝试运行」捕获的豫言异常,消息以 持久事务失败: 开头并保留原因文字;所有写入已回滚。处理入口自己抛出而未捕获的豫言异常在宿主边界表现为 RuntimeError: illegal cast,宿主会在消息后附上说明;需要向调用者报告具体原因时,处理入口应自己用「尝试运行」捕获,并把原因写进 完成持久事务 的结果。

直接访问持久仓

读取持久仓键值、写入持久仓键值、删除持久仓键、列举持久仓键值、清空持久仓 让应用在普通持久对象事件里不开事务直接访问持久仓,常用于只读一个键、写入后立即返回、扫描前缀或清库。它们只在持久对象事件中可用(事件种类以 durable- 开头),不能在 `durable-transaction` 处理入口内调用(那里的读写必须属于当前事务),在其他事件或事务入口内调用会抛出可捕获异常。单次调用是平台的一次原子存储操作;多次直接调用之间不构成事务,其间对象可能处理其他事件(除非在[持久独占](../持久独占/规范.汉语.md)区内)。

函数总表

| 函数 | 使用位置 | 说明 | | --- | --- | --- | | 执行持久事务 | 持久对象事件 | 0.1.0;失败改为抛可捕获异常 | | 读取持久事务参数、完成持久事务 | 事务入口 | 0.1.0 | | 读取持久事务键值、写入持久事务键值 | 事务入口 | 0.1.0 | | 删除持久事务键、列举持久事务键值、回滚持久事务 | 事务入口 | 0.2.0 新增 | | 读取持久仓键值、写入持久仓键值、删除持久仓键、列举持久仓键值、清空持久仓 | 非事务的持久对象事件 | 0.2.0 新增 |

读取持久事务键值 与 读取持久仓键值 返回存在标记和值的 JSON 文字:缺键返回阴与空字符串,已存 JSON null 返回阳与 null,二者不混淆。删除持久事务键 删除一个键(键原本不存在时无事发生);删除持久仓键 返回阳表示键原先存在。列举持久事务键值、列举持久仓键值 接受选项 JSON 对象文字,返回 JSON 数组文字 [[键,值],…],按键的 UTF-8 字节序排列(reverse 为真时逆序),值是存入的 JSON 值本身,不是再编码的字符串;事务内的列举能看到本事务尚未提交的写入与删除。清空持久仓 清空当前对象的全部持久数据(键值;SQLite 存储上还含 SQL 表,平台按兼容日期决定是否连告警一并清除)。

键、值与列举选项

键按 UTF-8 计须为 1 至 2048 字节。值是有效 JSON 文字,不超过 2 MiB,嵌套不超过 32 层,且不含宿主保留的单键对象——即只有一个成员且成员名为 $句柄、$未定义、$大整数 或 $数字 的对象(这些是宿主与豫言交换特殊值的记号,写入会被拒绝);含其他成员的对象、以及这些名字作为字符串值出现都是允许的。数字沿用 JSON 数字语义,绝对值超过 2^53−1 的整数应用字符串表达。

列举选项是 JSON 对象文字,字段均可省略:prefix、start(含)、startAfter(不含)、end(不含)为字符串,空字符串视同未指定;limit 为不小于 1 的整数;reverse 为布尔。start 与 startAfter 不能同时给出;出现其他字段、类型不符、limit 小于 1 时失败。省略 limit 时返回全部匹配项,但结果 JSON 文字超过 8 MiB 时失败,应用应按 limit 加 startAfter 分页。

失败情形

| 情形 | 类别 | | --- | --- | | 键长度越界;值不是有效 JSON、超过 2 MiB、嵌套过深或含保留单键对象;列举选项非法;列举结果超过 8 MiB | 违规或超限:抛可捕获的豫言异常,消息为中文原因 | | 在不允许的事件中调用(事务函数在事务入口外、直接访问函数在事务入口内或非持久对象事件) | 违规:抛可捕获的豫言异常 | | 执行持久事务 中处理入口失败、超时或平台报错 | 抛可捕获的豫言异常,写入已回滚 | | 交换文字超过宿主上限(16 MiB)、存储后端故障 | 平台或宿主故障:中止当前事件,豫言无法捕获 |

跨宿主一致性

任何实现须保持:值以 JSON 语义往返(读取 得到的文字与 写入 的值在 JSON 意义上相等,不承诺字节相同);缺键与 JSON null 可区分;列举的顺序、边界与 limit 语义如上;事务原子、事务期间其他事件排队、回滚后写入不可见;上述限额与失败类别。宿主可以选择不同的存储后端,但不得改变这些可观察结果。

一致性样例

设仓为空。写入持久仓键值 "p:a" "1"、"p:b" "2"、"p:c" "3" 后:读取持久仓键值 "p:a" 得(阳,1);读取持久仓键值 "无" 得(阴,空);列举持久仓键值 {"prefix":"p:","limit":2,"reverse":true} 得 [["p:c",3],["p:b",2]];列举持久仓键值 {"prefix":"","startAfter":"p:a"} 得 [["p:b",2],["p:c",3]]。写入 null 后读取得(阳,null)。写入 { 或 {"$句柄":"1"} 或长度 2049 字节的键抛异常且不改仓。

在事务入口内依次 删除持久事务键 "p:a"、写入持久事务键值 "p:d" "4",此时 列举持久事务键值 {"prefix":"p:"} 得 [["p:b",2],["p:c",3],["p:d",4]];完成持久事务 后仓中同样如此。若在写入 p:e 之后调用 回滚持久事务,则仓仍为提交前的样子。事务入口抛出未捕获异常时,执行持久事务 抛出以 持久事务失败: 开头的异常且仓不变。

边界

本包不提供 SQL、同步事务、批量读写、allowConcurrency、noCache、allowUnconfirmed 等平台选项,也不提供二进制或非 JSON 结构化克隆值;需要这些的应用另用适配库。既有数据中嵌套超过 32 层的值无法读出,读取它会使宿主中止当前事件。首版借标准库字符串承载 JSON 值,应用可用豫言 癸象 在自身逻辑中解析与构造;事务重入 _start 是适配实现,后续可换成类型化回调,应用所见的原子性与值语义不变。宿主的事件时限配置(执行配置.json)属宿主构建,不属于本接口。本包只用于已授权的当前持久仓,仓的名称与授权由宿主与部署配置决定。

依赖

查看包配置

上传历史

当前上传修订:1 ·

  1. 上传修订 1
    下载 ZIP

包层级

父包:豫言操作系统接口

没有子包。