ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TigerBeetle Python 客户端入门:用 basic 示例跑通“建账户—转账—校验余额“全流程

TigerBeetle Python 客户端入门:用 basic 示例跑通“建账户—转账—校验余额“全流程 TigerBeetle Python 客户端入门用 basic 示例跑通建账户—转账—校验余额全流程【免费下载链接】tigerbeetleThe financial transactions database designed for mission critical safety and performance.项目地址: https://gitcode.com/GitHub_Trending/ti/tigerbeetle导读本文以 TigerBeetle 仓库中 basic 示例 为骨架完整讲解如何使用 Python 客户端tigerbeetlepip 包连接 TigerBeetle 数据库安装客户端、启动服务端、创建两个账户、发起一笔转账最后回查账户余额并用断言逐项校验借方debits与贷方credits的变化。读完本文你将掌握 Python 客户端的最小可用闭环并理解账户/转账的数据结构、状态码枚举与批处理batching等底层约定可以直接照抄代码跑通你的第一个 TigerBeetle 事务。1. 示例概览这个 basic 项目做了什么示例代码位于 src/clients/python/samples/basic/main.py整个流程只有三步却覆盖了 TigerBeetle 最核心的三种操作创建账户用create_accounts批量创建两个账户id 分别为1和2创建转账用create_transfers将金额10从账户1debit借方转到账户2credit贷方回查并校验余额用lookup_accounts取回两个账户断言账户1为debits_posted 10、credits_posted 0账户2为debits_posted 0、credits_posted 10。这本质上就是一个最小双账户转账用例是理解 TigerBeetle 借贷记账模型double-entry bookkeeping最快的入口。仓库里还有两个进阶示例与之对照two-phase两阶段转账先 PENDING 再 POST和 two-phase-many多条待定转账交替 post/void可在跑通 basic 后继续阅读。2. 环境与前置条件根据 basic 示例 README 与 tigerbeetle-python 客户端文档运行本示例需要满足操作系统Linux 5.6 是唯一的生产环境支持平台为便于开发macOS 与 Windows 也受支持。Python3.7PyPy 等实现亦可。Python 包内部通过 ctypes 加载随包分发的原生共享库tb_client。从 src/clients/python/src/tigerbeetle/lib.py 的加载逻辑可以看到它按平台自动选择动态库文件架构仅支持x86_64/amd64与aarch64/arm64Linux 下区分 glibc-gnu.2.27后缀与 musl-musl后缀其他 libc 会抛出NativeError: Unsupported libc系统仅支持 Linux、Darwin、Windows其他平台会抛出NativeError: Unsupported system。也就是说只要你的机器满足上述架构与系统组合pip install tigerbeetle后无需任何额外编译即可使用。3. 安装 Python 客户端进入示例目录后直接安装$ cd tigerbeetle/src/clients/python/samples/basic $ pip install tigerbeetle安装完成后在 Python 中做一次冒烟测试即可确认环境正常import os import tigerbeetle as tb print(Import OK!) # 如需开启调试日志可通过 Python 内置 logging 模块 # logging.basicConfig(levellogging.DEBUG) # tb.configure_logging(debugTrue)tb.configure_logging(debugTrue)来自 src/clients/python/src/tigerbeetle/client.py它把 TigerBeetle 原生层的日志回调桥接到 Python 的logging体系排查问题时非常有用。4. 启动 TigerBeetle 服务端示例 README 要求先按仓库主 README 的步骤启动 TigerBeetle。单副本集群的最小启动方式见 README.md$ curl -Lo tigerbeetle.zip https://linux.tigerbeetle.com unzip tigerbeetle.zip $ ./tigerbeetle version $ ./tigerbeetle format --cluster0 --replica0 --replica-count1 --development 0_0.tigerbeetle $ ./tigerbeetle start --addresses3000 --development 0_0.tigerbeetle关键点cluster示例使用cluster_id0与format --cluster0保持一致地址默认监听localhost:3000。如果服务端不在该地址设置环境变量TB_ADDRESS指向完整地址即可$ export TB_ADDRESS127.0.0.1:3000地址的合法写法来自客户端文档3000→ 解释为127.0.0.1:3000127.0.0.1:3000→ 保持不变127.0.0.1→ 解释为127.0.0.1:30013001是默认端口5. 运行示例服务端就绪后在示例目录下执行$ python3 main.py程序用assert做自我校验全部通过后打印ok。整个 main.py 的运行逻辑如下节所示。6. 逐行拆解 main.py6.1 创建客户端import os import tigerbeetle as tb with tb.ClientSync(cluster_id0, replica_addressesos.getenv(TB_ADDRESS, 3000)) as client: ...cluster_id必须与启动集群时指定的 cluster 一致replica_addresses是所有副本的地址列表本例单副本取环境变量TB_ADDRESS缺省3000ClientSync是同步客户端用with语句进入上下文退出时自动close()见 src/clients/python/src/tigerbeetle/client.py 中__exit__→close()的实现。6.2 创建账户account_results client.create_accounts([ tb.Account( id1, ledger1, code1, ), tb.Account( id2, ledger1, code1, ), ])tb.Account是 Python 客户端定义的 dataclasssrc/clients/python/src/tigerbeetle/bindings.py字段与 wire 格式一一对应字段位宽说明idu128账户唯一标识示例用1/2生产环境建议用tb.id()生成基于 ULID 的 128 位可排序 IDdebits_pending/debits_postedu128借方待定/已过账金额新建账户必须为 0服务端会校验credits_pending/credits_postedu128贷方待定/已过账金额同上user_data_128/user_data_64/user_data_32u128/u64/u32应用自定义数据可用于关联业务 ID、做过滤查询ledgeru32账本号转账双方必须在同一 ledger且与账户 ledger 一致codeu16业务编码如账户类型、币种用于查询过滤flagsu16位标志见下文Flags小节timestampu64必须为 0由服务端分配见TIMESTAMP_MUST_BE_ZERO错误码示例中所有金额/用户数据字段都取默认值 0仅显式设置id、ledger、code这是最简单合法的账户。6.3 校验建账结果print(account_results) assert len(account_results) 2 assert account_results[0].status tb.CreateAccountStatus.CREATED assert account_results[1].status tb.CreateAccountStatus.CREATEDcreate_accounts的返回结果与请求一一对应每个结果包含statusCreateAccountStatus枚举。成功为CREATED数值0xFFFFFFFF见 bindings.pytimestamp本次操作由服务端分配的时间戳。值得注意的是重复提交相同id的账户不会报失败而是返回EXISTS携带原账户的时间戳这正是 TigerBeetle 幂等语义的基础——重试是安全的。6.4 创建转账transfers_results client.create_transfers([ tb.Transfer( id1, debit_account_id1, credit_account_id2, amount10, ledger1, code1, ), ])tb.Transfer同样是与 wire 格式对应的 dataclass字段位宽说明idu128转账唯一标识TigerBeetle 用它做幂等去重同 id 的转账只能提交一次debit_account_idu128借方账户资金流出方credit_account_idu128贷方账户资金流入方必须与借方不同amountu128转账金额0 amount普通转账金额不能为 0pending_idu128两阶段转账时指向 PENDING 转账的 id普通转账为 0timeoutu32仅对 PENDING 转账有意义到期自动过期单位秒纳秒见源码语义普通转账为 0ledger/codeu32/u16同账户转账 ledger 必须等于双方账户 ledgerflagsu16位标志普通转账为 0timestampu64必须为 0由服务端分配6.5 校验转账结果print(transfers_results) assert len(transfers_results) 1 assert transfers_results[0].status tb.CreateTransferStatus.CREATEDCreateTransferStatus.CREATED同样是0xFFFFFFFF。与账户类似若同 id 转账已存在会返回EXISTS系列状态码。完整错误码枚举如DEBIT_ACCOUNT_NOT_FOUND、CREDIT_ACCOUNT_NOT_FOUND、ACCOUNTS_MUST_HAVE_THE_SAME_LEDGER、EXCEEDS_CREDITS等都在 bindings.py 中定义可用于精细化错误处理。6.6 回查账户并校验余额accounts client.lookup_accounts([1, 2]) assert len(accounts) 2 for account in accounts: if account.id 1: assert account.debits_posted 10 assert account.credits_posted 0 elif account.id 2: assert account.debits_posted 0 assert account.credits_posted 10 else: raise Exception(Unexpected account: account) print(ok)这里体现了 TigerBeetle 记账模型的核心语义debit 是钱从哪来账户 1 是借方debits_posted从 0 变为 10credit 是钱到哪去账户 2 是贷方credits_posted从 0 变为 10借贷平衡debits_posted账户 1credits_posted账户 2 10系统内部保证总借方恒等于总贷方。lookup_accounts也是批处理接口返回的账户顺序不一定与请求 id 顺序一致因此代码用account.id做区分而不是依赖索引——这一点在客户端 README 的 Account Lookup 一节中有明确说明。7. 关键 API 与常量速查示例之外同一个 Python 客户端还提供以下操作均来自 bindings.py 的StateMachineMixin/AsyncStateMachineMixin与 client.py 的同步/异步封装方法说明create_accounts/create_transfers批量创建账户/转账lookup_accounts/lookup_transfers按 id 批量查询无匹配则不返回顺序不保证get_account_transfers/get_account_balances按账户过滤查询流水/时点余额预览 API要求账户带HISTORY标志query_accounts/query_transfers按字段交集 时间范围查询预览 API常用常量tb.id()生成基于 ULID 的 128 位全局唯一、按时间可排序 ID实现见 client.py 的_IDGeneratortb.AMOUNT_MAX2**128 - 1两阶段转账 post 时表示post 掉整个 pending 金额tb.AccountFlags/tb.TransferFlagsenum.IntFlag位标志可用|组合例如AccountFlags.LINKED/TransferFlags.LINKED链接事件链上全部成功或全部回滚AccountFlags.DEBITS_MUST_NOT_EXCEED_CREDITS/CREDITS_MUST_NOT_EXCEED_DEBITS余额约束AccountFlags.HISTORY开启历史余额保留TransferFlags.PENDING/POST_PENDING_TRANSFER/VOID_PENDING_TRANSFER两阶段转账三要素。8. 从 basic 到生产必须了解的批处理与幂等basic 示例只提交了 2 个账户和 1 笔转账但 TigerBeetle 的性能模型高度依赖批处理客户端文档 Batching 一节客户端实例是线程安全的多个并发请求可被客户端自动合并批处理应用侧仍应尽量在单次调用中提交尽可能多的事件。例如插入 100 万笔转账如果逐笔串行提交插入速率将只是潜在能力的零头应始终尽可能多地批量提交单批最大条数由服务端配置决定默认值为8189与测试文件 src/clients/python/tests/test_basic.py 中BATCH_MAX 8189一致。超过上限会抛出TooMuchDataErrorbatch [] # 待创建的转账列表 BATCH_SIZE 8189 for i in range(0, len(batch), BATCH_SIZE): transfers_results client.create_transfers( batch[i:min(len(batch), i BATCH_SIZE)], ) # 结果处理略另一个生产级要点是幂等TigerBeetle 以id作为去重键重复提交同 id 的账户/转账会返回EXISTS或EXISTS_WITH_DIFFERENT_*系列而不会重复入账。因此应用可以用业务幂等键作为 id配合 可靠事务提交 的指引实现重试安全的提交。此外客户端无限重试、不设单请求超时关闭客户端时所有在途请求被取消并向调用方返回错误——即使收到错误请求仍可能已被服务端处理这正是需要用 id 幂等兜底的原因。9. 进阶两阶段转账Pending → Post/Voidbasic 示例是即时过账的单阶段转账。如果业务需要预授权—确认/取消如押金、扣款审批TigerBeetle 原生支持两阶段转账可参考 two-phase 示例发起待定转账flagstb.TransferFlags.PENDING金额进入双方的debits_pending/credits_pending不计入已过账余额确认postflagstb.TransferFlags.POST_PENDING_TRANSFERpending_id指向待定转账系统原子地把pending回滚、把金额应用到debits_posted/credits_posted取消voidflagstb.TransferFlags.VOID_PENDING_TRANSFER只回滚pending不应用到posted。post 时amount可设为tb.AMOUNT_MAX表示全部确认。待定转账还可设置timeout到期后自动过期测试 test_basic.py 的test_cannot_void_an_expired_transfer展示了过期语义。更复杂的交替 post/void 场景可参考 two-phase-many 示例。10. 常见错误与排查InitErrorClientSync初始化失败。多为 cluster id 不匹配、地址不可达或原生库未加载检查平台/架构是否受支持见 lib.py。IntegerOverflowError字段超出位宽。ctypes 绑定在提交前会对每个整数字段做范围校验如 u128、u64、u32、u16负数或过大值都会抛出该异常对应测试 test_basic.py 的test_range_check_*系列。TooMuchDataError单批请求超过服务端client_request_batch_max默认 8189。ClientClosedError/ClientEvictedError/ClientReleaseTooLowError/ClientReleaseTooHighError客户端关闭后被使用、被服务端淘汰、或客户端库版本与服务端不兼容版本过旧/过新。这些异常类型定义在 client.py。TIMESTAMP_MUST_BE_ZERO手动给Account.timestamp/Transfer.timestamp传了非 0 值时间戳一律由服务端分配。11. 小结通过 basic 示例 与 main.py你已经跑通了 TigerBeetle Python 客户端的最小闭环ClientSync连接 →create_accounts建账 →create_transfers转账 →lookup_accounts校验借贷余额。在此基础上结合 tigerbeetle-python 客户端文档 中关于 Flags、两阶段转账、批处理、链式事件与导入事件的章节即可将这套最小示例扩展为具备余额约束、预授权、历史查询的生产级记账系统。相关资源basic 示例 README本文主体来源basic 示例代码 main.pytigerbeetle-python 客户端完整文档Python 客户端核心实现 client.pyPython 客户端数据类型与状态码 bindings.py原生库加载与整型校验 lib.pyPython 客户端集成测试 test_basic.py两阶段转账示例仓库主 README 的服务端启动步骤【免费下载链接】tigerbeetleThe financial transactions database designed for mission critical safety and performance.项目地址: https://gitcode.com/GitHub_Trending/ti/tigerbeetle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表