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

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

使用装饰器启用事务

import { Database } from 'vona-module-a-orm';

class ServicePost {
@Database.transaction()
async transaction() {
// insert
const post = await this.scope.model.post.insert({
title: 'Post001',
});
// update
await 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() {
// insert
const post = await this.scope.model.post.insert({
title: 'Post001',
});
// cache
await 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执行相应的补偿操作。当数据库事务回滚时,让数据库数据与缓存数据保持一致

Node生态中最优雅的数据库事务处理机制的更多相关文章

  1. [转]Node.js中koa使用redis数据库

    本文转自:https://blog.csdn.net/offbye/article/details/52452322 Redis是一个常用的Nosql数据库,一般用来代替Memcached做缓存服务, ...

  2. 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...

  3. [转]在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    本文转自:https://www.cnblogs.com/kongxianghai/p/5582661.html Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用Ja ...

  4. 前端走进机器学习生态,在 Node.js 中使用 Python

    这次给大家带来一个好东西,它的主要用途就是能让大家在 Node.js 中使用 Python 的接口和函数.可能你看到这里会好奇,会疑惑,会不解,我 Node.js 大法那么好,干嘛要用 Python ...

  5. nodejs中如何使用mysql数据库[node-mysql翻译]

    nodejs中如何使用mysql数据库 db-mysql因为node-waf: not found已经不能使用,可以使用mysql代替. 本文主要是[node-mysql]: https://www. ...

  6. Node.js中的Session,不要觉得简单哦。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .学习网站上有对应 ...

  7. Atitti 数据库事务处理 attilax总结

    Atitti 数据库事务处理 attilax总结 1.1. 为什么要传递Connection?1 1.2. 两种事务处理方式,一种是编程式事务处理;一种是声明...2 1.3. 事务隔离级别 2 1. ...

  8. 十三、EnterpriseFrameWork框架核心类库之数据库操作(多数据库事务处理)

    本章介绍框架中封装的数据库操作的一些功能,在实现的过程中费了不少心思,针对不同数据库的操作(SQLServer.Oracle.DB2)这方面还是比较简单的,用工厂模式就能很好解决,反而是在多数据库同时 ...

  9. Node.js 连接 MySQL 并进行数据库操作

    Node.js 连接 MySQL 并进行数据库操作  按照这篇操作mysql的指引,我远程操作了我另一台电脑的mysql数据库. var mysql = require('mysql'); var c ...

  10. 在Node应用中避免“Dot Hell”

    转载自:http://blog.leapoahead.com/2015/09/03/prevent-node-require-dot-hell/ 在Node应用中,我们使用require来加载模块.在 ...

随机推荐

  1. DPDI:Kettle任务调度与管理的高效解决方案

    DPDI:Kettle任务调度与管理的高效解决方案 引言 在企业大规模数据处理领域,Kettle(Pentaho Data Integration)作为一款广受欢迎的开源ETL工具,以其强大的数据处理 ...

  2. Cornell University's Textbook Reading Systems(教科书阅读系统-康奈尔大学)

    Textbook Reading Systems Textbook reading systems help you interact with the information in textbook ...

  3. SciTech-Mathmatics-Physics-Particle+Movement-Election-The Maxwell Equations-Wave-Particle Duality. 电场(Election)•磁场(磁通量)•光(Photon) + Hertz's Proof。

    The Maxwell Equations: 电.磁.光 Static Electric Field Static Magnetic Field Changing Electric Field Cha ...

  4. Nginx通过反向代理将https访问地址代理至内网-九五小庞

    server { listen 7090 default_server; listen [::]:7090 default_server; #server_name _; root /usr/shar ...

  5. Linux下设置MySQL的环境变量:-九五小庞

    Linux下设置MySQL的环境变量: 在/etc/profile中添加: export PATH=$PATH:/usr/local/MySQL/bin 重新加载配置文件 source /etc/pr ...

  6. Win11正式版网络错误访问提示0x800704cf的问题

    有深度技术的用户在win11正式版系统电脑中出现网络错误提示0x800704cf错误代码,那么如何解决这个问题?接下来,深度官网小编为大家带来详细的解决方案,大家可以一起来看看. 当 Win11 正式 ...

  7. Windows11系统玩游戏卡顿掉帧的问题

    有很多电脑基地用户都安装了win11系统,大家都知道Win11的性能要比Win10高一些,因此很多喜欢玩游戏的朋友想要尝试使用Win11玩游戏,但是,又不知道Windows11玩游戏是否会卡顿下面就跟 ...

  8. 我把“咒语”喂给AI,给自己做了张“传说级”名片

    你有没有过这种瞬间: 在一些场合,当别人问"你是做什么的?" 你张了张嘴,发现自己那复杂的.多线程的.充满创造力的工作,被一句"我是做设计的/做市场的/做咨询的" ...

  9. MPI java多线程

    我的计算机是24核的工作站,想进行并行计算.现在有两种选择:java的多线程和MPICH+mpiJava的MPI编程.请问二者有什么区别呢?哪个会更快一点?我搜了一下,好像说MPI是多进程的,这是不是 ...

  10. Linux touch命令的使用

    用touch修改某文件的时间戳到当前时刻 xinlin@ubuntu:~$ ll test-rwxrw-r-- 1 xinlin xinlin 34 Sep 17 21:49 test*xinlin@ ...