找回密码
 立即注册
首页 业界区 业界 这个Database Transaction功能多多,你用过吗? ...

这个Database Transaction功能多多,你用过吗?

梢疠 2025-8-21 12:09:13
Vona 是一款直观、优雅、强大的 Node.js Web 框架,用于快速开发任何规模的企业级应用。首创 DTO 动态推断与生成能力,从而显著提升开发效率和开发体验。Vona ORM 对数据库事务提供了完整的支持,提供了直观、优雅、强大的特性:

  • 使用装饰器启用事务
  • 事务传播机制
  • 事务补偿机制
  • 确保数据库与缓存数据一致性
使用装饰器启用事务
  1. import { Database } from 'vona-module-a-orm';
  2. class ServicePost {
  3.   @Database.transaction()
  4.   async transaction() {
  5.     // insert
  6.     const post = await this.scope.model.post.insert({
  7.       title: 'Post001',
  8.     });
  9.     // update
  10.     await this.scope.model.post.update({
  11.       id: post.id,
  12.       title: 'Post001-Update',
  13.     });
  14.   }
  15. }  
复制代码
手工启用事务

1. 使用当前数据源
  1. class ServicePost {
  2.   async transactionManually() {
  3.     const db = this.bean.database.current;
  4.     await db.transaction.begin(async () => {
  5.       await this.scope.model.post.update({ id: 1, title: 'Post001_Update' });
  6.     });
  7.   }
  8. }
复制代码
2. 使用指定数据源
  1. class ServicePost {
  2.   async transactionManually() {
  3.     const db = this.bean.database.getDb({ clientName: 'default' });
  4.     await db.transaction.begin(async () => {
  5.       const modelPost = this.scope.model.post.newInstance(db);
  6.       await modelPost.update({ id: 1, title: 'Post001_Update' });
  7.     });
  8.   }
  9. }
复制代码
事务参数
  1. class ServicePost {
  2.   @Database.transaction({
  3. +   isolationLevel: 'READ_COMMITTED',
  4. +   propagation: 'REQUIRED'
  5.   })
  6.   async transaction() {
  7.     ...
  8.   }
  9. }  
复制代码
  1. class ServicePost {
  2.   async transactionManually() {
  3.     const db = this.bean.database.getDb({ clientName: 'default' });
  4.     await db.transaction.begin(
  5.       async () => {
  6.         ...
  7.       },
  8.       {
  9. +       isolationLevel: 'READ_COMMITTED',
  10. +       propagation: 'REQUIRED',
  11.       }
  12.     );
  13.   }
  14. }  
复制代码
事务参数:isolationLevel

名称说明DEFAULT数据库相关的缺省isolationLevelREAD_UNCOMMITTEDREAD_COMMITTEDREPEATABLE_READSERIALIZABLESNAPSHOT事务参数:propagation

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

当事务成功或者失败时执行一些逻辑
1. 成功补偿
  1. this.bean.database.current.commit(async () => {
  2.   // do something when success
  3. });
复制代码
2. 失败补偿
  1. this.bean.database.current.compensate(async () => {
  2.   // do something when failed
  3. });
复制代码
事务与Cache数据一致性

许多框架使用最简短的用例来证明是否高性能,而忽略了业务复杂性带来的性能挑战。随着业务的增长和变更,项目性能就会断崖式下降,各种优化补救方案让项目代码繁杂冗长。而 Vona 正视大型业务的复杂性,从框架核心引入缓存策略,并实现了二级缓存、Query缓存和Entity缓存等机制,轻松应对大型业务系统的开发,可以始终保持代码的优雅和直观
Vona 系统对数据库事务与缓存进行了适配,当数据库事务失败时会自动执行缓存的补偿操作,从而让数据库数据与缓存数据始终保持一致
针对这个场景,Vona 提供了内置的解决方案
1. 使用当前数据源
  1. class ServicePost {
  2.   @Database.transaction()
  3.   async transaction() {
  4.     // insert
  5.     const post = await this.scope.model.post.insert({
  6.       title: 'Post001',
  7.     });
  8.     // cache
  9.     await this.scope.cacheRedis.post.set(post, post.id);
  10.   }
  11. }  
复制代码

  • 当新建数据后,将数据放入 redis 缓存中。如果这个事务出现异常,就会进行数据回滚,同时缓存数据也会回滚,从而让数据库数据与缓存数据保持一致
2. 使用指定数据源
  1. class ServicePost {
  2.   async transactionManually() {
  3.     const db = this.bean.database.getDb({ clientName: 'default' });
  4.     await db.transaction.begin(async () => {
  5.       const modelPost = this.scope.model.post.newInstance(db);
  6.       const post = await modelPost.insert({ title: 'Post001' });
  7.       await this.scope.cacheRedis.post.set(post, post.id, { db });
  8.     });
  9.   }
  10. }  
复制代码

  • 如果对指定的数据库进行操作,那么就需要将数据库对象db传入缓存,从而让缓存针对数据库对象db执行相应的补偿操作。当数据库事务回滚时,让数据库数据与缓存数据保持一致

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册