当前位置: 首页 > news >正文

Node生态中最优雅的数据库事务处理机制

Vona ORM 对数据库事务提供了完整的支持,提供了直观、优雅、强大的特性:

  1. 使用装饰器启用事务
  2. 事务传播机制
  3. 事务补偿机制
  4. 确保数据库与缓存数据一致性

使用装饰器启用事务

import { Database } from 'vona-module-a-orm';class ServicePost {@Database.transaction()async transaction() {// insertconst post = await this.scope.model.post.insert({title: 'Post001',});// updateawait this.scope.model.post.update({id: post.id,title: 'Post001-Update',});}
}  

手工启用事务

1. 使用当前数据源

class ServicePost {async transactionManually() {const db = this.bean.database.current;await db.transaction.begin(async () => {await this.scope.model.post.update({ id: 1, title: 'Post001_Update' });});}
}

2. 使用指定数据源

class ServicePost {async transactionManually() {const db = this.bean.database.getDb({ clientName: 'default' });await db.transaction.begin(async () => {const modelPost = this.scope.model.post.newInstance(db);await modelPost.update({ id: 1, title: 'Post001_Update' });});}
}

事务参数

class ServicePost {@Database.transaction({
+   isolationLevel: 'READ_COMMITTED',
+   propagation: 'REQUIRED'})async transaction() {...}
}  
class ServicePost {async transactionManually() {const db = this.bean.database.getDb({ clientName: 'default' });await db.transaction.begin(async () => {...},{
+       isolationLevel: 'READ_COMMITTED',
+       propagation: 'REQUIRED',});}
}  

事务参数:isolationLevel

名称 说明
DEFAULT 数据库相关的缺省isolationLevel
READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE
SNAPSHOT

事务参数:propagation

Vona ORM 支持数据库事务传播机制

名称 说明
REQUIRED 默认的事务传播级别。如果当前存在事务, 则加入该事务。如果当前没有事务, 则创建一个新的事务
SUPPORTS 如果当前存在事务,则加入该事务. 如果当前没有事务, 则以非事务的方式继续运行
MANDATORY 强制性。如果当前存在事务, 则加入该事务。如果当前没有事务,则抛出异常
REQUIRES_NEW 创建一个新的事务。如果当前存在事务, 则把当前事务挂起。也就是说不管外部方法是否开启事务,总是开启新的事务, 且开启的事务相互独立, 互不干扰
NOT_SUPPORTED 以非事务方式运行。如果当前存在事务,则把当前事务挂起(不用)
NEVER 以非事务方式运行。如果当前存在事务,则抛出异常

事务补偿机制

当事务成功或者失败时执行一些逻辑

1. 成功补偿

this.bean.database.current.commit(async () => {// do something when success
});

2. 失败补偿

this.bean.database.current.compensate(async () => {// do something when failed
});

事务与Cache数据一致性

许多框架使用最简短的用例来证明是否高性能,而忽略了业务复杂性带来的性能挑战。随着业务的增长和变更,项目性能就会断崖式下降,各种优化补救方案让项目代码繁杂冗长。而 Vona 正视大型业务的复杂性,从框架核心引入缓存策略,并实现了二级缓存Query缓存Entity缓存等机制,轻松应对大型业务系统的开发,可以始终保持代码的优雅和直观

Vona 系统对数据库事务与缓存进行了适配,当数据库事务失败时会自动执行缓存的补偿操作,从而让数据库数据与缓存数据始终保持一致

针对这个场景,Vona 提供了内置的解决方案

1. 使用当前数据源

class ServicePost {@Database.transaction()async transaction() {// insertconst post = await this.scope.model.post.insert({title: 'Post001',});// cacheawait this.scope.cacheRedis.post.set(post, post.id);}
}  
  • 当新建数据后,将数据放入 redis 缓存中。如果这个事务出现异常,就会进行数据回滚,同时缓存数据也会回滚,从而让数据库数据与缓存数据保持一致

2. 使用指定数据源

class ServicePost {async transactionManually() {const db = this.bean.database.getDb({ clientName: 'default' });await db.transaction.begin(async () => {const modelPost = this.scope.model.post.newInstance(db);const post = await modelPost.insert({ title: 'Post001' });await this.scope.cacheRedis.post.set(post, post.id, { db });});}
}  
  • 如果对指定的数据库进行操作,那么就需要将数据库对象db传入缓存,从而让缓存针对数据库对象db执行相应的补偿操作。当数据库事务回滚时,让数据库数据与缓存数据保持一致
http://www.jsqmd.com/news/6295/

相关文章:

  • 详细介绍:扒透 STL 底层!map/set 如何封装红黑树?迭代器逻辑 + 键值限制全手撕----《Hello C++ Wrold!》(23)--(C/C++)
  • 死锁的处理策略-预防死锁
  • 跨网文件安全交换系统:提升数据传输安全性和合规性
  • ArcGIS 公众号推荐
  • 跨网文件交换系统:数字化时代企业与机构的数据安全传输利器
  • 缩放 div
  • Redis从零讲解 - 详解
  • 【2025-09-29】团队合作
  • 杂凑算法学习笔记
  • pg库支持扩展postgis
  • kuboard部署启用3个etcd(k8s单个master)
  • odoo18应用、队列服务器分离(SSHFS) - 详解
  • 数据库服务分布架构(MyCAT)
  • 题解:P14038 [PAIO 2025] Adventure Plan
  • 20231414_王仕琪_密码技术密码杂凑算法学习笔记
  • 调度算法易错概念总结
  • 堆设置了8G,java进程却占用了12G内存
  • Huxe 推出主动式 AI 音频服务,无感内容消费;OpenAI 推出 ChatGPT Pulse:主动提供个性化信息丨日报
  • C++学习:C++类型转换专栏 - 指南
  • NAFNet (Simple Baselines for Image Restoration) 阅读笔记 - 教程
  • 解决OpenWrt系统上出现“git: remote-https is not a git command...”的问题
  • 密码技术概论
  • IntelliJ IDEA 中 Shared Build Process Heap Size 的重要性与配置
  • 企业数字化转型战略规划:从愿景到落地的完整路径
  • 贝叶斯学习笔记 - 详解
  • 设计模式-结构性设计模式(针对类与对象的组织结构) - 指南
  • 凯利公式在期货交易中的应用
  • 在确定性之外:关于AGI与ASI愿景的一些补充思考 (附阿里CEO云栖大会演讲全文) - 指南
  • AT_agc054_c [AGC054C] Roughly Sorted
  • Ubuntu 24和25配置apt国内源