Nodejs sequelize 事物处理

2024-09-07 02:48
文章标签 处理 nodejs 事物 sequelize

本文主要是介绍Nodejs sequelize 事物处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Transactions - 事务

Sequelize 支持两种使用事务的方法:

  • 一个将根据 promise 链的结果自动提交或回滚事务,(如果启用)用回调将该事务传递给所有调用
  • 而另一个 leave committing,回滚并将事务传递给用户。

主要区别在于托管事务使用一个回调,对非托管事务而言期望 promise 返回一个 promise 的结果。

托管事务(auto-callback)

托管事务自动处理提交或回滚事务。你可以通过将回调传递给 sequelize.transaction 来启动托管事务。

注意回传传递给 transaction 的回调是否是一个 promise 链,并且没有明确地调用t.commit()或 t.rollback()。 如果返回链中的所有 promise 都已成功解决,则事务被提交。 如果一个或几个 promise 被拒绝,事务将回滚。

return sequelize.transaction(function (t) {// 在这里链接您的所有查询。 确保你返回他们。return User.create({firstName: 'Abraham',lastName: 'Lincoln'}, {transaction: t}).then(function (user) {return user.setShooter({firstName: 'John',lastName: 'Boothe'}, {transaction: t});});}).then(function (result) {// 事务已被提交// result 是 promise 链返回到事务回调的结果
}).catch(function (err) {// 事务已被回滚// err 是拒绝 promise 链返回到事务回调的错误
});

抛出错误到回滚

使用托管事务时,你应该 永不 手动提交或回滚事务。 如果所有查询都成功,但您仍然希望回滚事务(例如因为验证失败),则应该抛出一个错误来断开和拒绝链接:

return sequelize.transaction(function (t) {return User.create({firstName: 'Abraham',lastName: 'Lincoln'}, {transaction: t}).then(function (user) {// 查询成功,但我们仍然想回滚!throw new Error();});
});

自动将事务传递给所有查询

在上面的例子中,事务仍然是手动传递的,通过传递 {transaction:t} 作为第二个参数。 要自动将事务传递给所有查询,您必须安装 continuation local storage (CLS) 模块,并在您自己的代码中实例化一个命名空间:

const cls = require('continuation-local-storage'),namespace = cls.createNamespace('my-very-own-namespace');

要启用CLS,您必须通过使用sequelize构造函数的静态方法来告诉Sequelize要使用的命名空间:

const Sequelize = require('sequelize');
Sequelize.useCLS(namespace);new Sequelize(....);

请注意, useCLS() 方法在 构造函数 上,而不是在 sequelize 的实例上。 这意味着所有实例将共享相同的命名空间,并且 CLS 是全部或全无方式 - 你不能仅在某些实例中启用它。

CLS 的工作方式就像一个用于回调的本地线程存储。 这在实践中意味着不同的回调链可以通过使用 CLS 命名空间来访问局部变量。 当启用 CLS 时,创建新事务时,Sequelize 将在命名空间上设置 transaction 属性。 由于回调链中设置的变量对该链是私有的,因此可以同时存在多个并发事务:

sequelize.transaction(function (t1) {namespace.get('transaction') === t1; // true
});sequelize.transaction(function (t2) {namespace.get('transaction') === t2; // true
});

在大多数情况下,你不需要直接访问 namespace.get('transaction'),因为所有查询都将自动在命名空间中查找事务:

sequelize.transaction(function (t1) {// 启用 CLS 后,将在事务中创建用户return User.create({ name: 'Alice' });
});

在使用 Sequelize.useCLS() 后,从 sequelize 返回的所有 promise 将被修补以维护 CLS 上下文。 

并行/部分事务

你可以在一系列查询中执行并发事务,或者将某些事务从任何事务中排除。 使用 {transaction: } 选项来控制查询所属的事务:

不启用CLS

sequelize.transaction(function (t1) {return sequelize.transaction(function (t2) {// 启用CLS,这里的查询将默认使用 t2    // 通过 `transaction` 选项来定义/更改它们所属的事务。return Promise.all([User.create({ name: 'Bob' }, { transaction: null }),User.create({ name: 'Mallory' }, { transaction: t1 }),User.create({ name: 'John' }) // 这将默认为 t2]);});
});

隔离等级

启动事务时可能使用的隔离等级:

Sequelize.Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED // "READ UNCOMMITTED"
Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED // "READ COMMITTED"
Sequelize.Transaction.ISOLATION_LEVELS.REPEATABLE_READ  // "REPEATABLE READ"
Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE // "SERIALIZABLE"

默认情况下,sequelize 使用数据库的隔离级别。 如果要使用不同的隔离级别,请传入所需级别作为第一个参数:

return sequelize.transaction({isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE}, function (t) {//  你的事务});

注意: 在MSSQL的情况下,SET ISOLATION LEVEL 查询不被记录, 指定的 isolationLevel 直接传递到tedious

非托管事务(then-callback)

非托管事务强制您手动回滚或提交交易。 如果不这样做,事务将挂起,直到超时。 要启动非托管事务,请调用 sequelize.transaction() 而不用 callback(你仍然可以传递一个选项对象),并在返回的 promise 上调用 then。 请注意,commit() 和 rollback() 返回一个 promise。

return sequelize.transaction().then(function (t) {return User.create({firstName: 'Homer',lastName: 'Simpson'}, {transaction: t}).then(function (user) {return user.addSibling({firstName: 'Lisa',lastName: 'Simpson'}, {transaction: t});}).then(function () {return t.commit();}).catch(function (err) {return t.rollback();});
});

参数

可以使用options对象作为第一个参数来调用transaction方法,这允许配置事务。

return sequelize.transaction({ /* options */ });

以下选项(使用默认值)可用:

{autocommit: true,isolationLevel: 'REPEATABLE_READ',deferrable: 'NOT DEFERRABLE' // postgres 的默认设置
}

在为 Sequelize 实例或每个局部事务初始化时,isolationLevel可以全局设置:

// 全局
new Sequelize('db', 'user', 'pw', {isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE
});// 局部
sequelize.transaction({isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE
});

deferrable 选项在事务开始后触发一个额外的查询,可选地将约束检查设置为延迟或立即。 请注意,这仅在PostgreSQL中受支持。

sequelize.transaction({// 推迟所有约束:deferrable: Sequelize.Deferrable.SET_DEFERRED,// 推迟具体约束:deferrable: Sequelize.Deferrable.SET_DEFERRED(['some_constraint']),// 不推迟约束:deferrable: Sequelize.Deferrable.SET_IMMEDIATE
})

使用其他 Sequelize 方法

transaction 选项与其他大多数选项一起使用,通常是方法的第一个参数。
对于取值的方法,如 .create.update().updateAttributes() 等。应该传递给第二个参数的选项。
如果不确定,请参阅API文档中的用于确定签名的方法。


这篇关于Nodejs sequelize 事物处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143840

相关文章

Springboot处理跨域的实现方式(附Demo)

《Springboot处理跨域的实现方式(附Demo)》:本文主要介绍Springboot处理跨域的实现方式(附Demo),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录Springboot处理跨域的方式1. 基本知识2. @CrossOrigin3. 全局跨域设置4.

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

Python实现自动化接收与处理手机验证码

《Python实现自动化接收与处理手机验证码》在移动互联网时代,短信验证码已成为身份验证、账号注册等环节的重要安全手段,本文将介绍如何利用Python实现验证码的自动接收,识别与转发,需要的可以参考下... 目录引言一、准备工作1.1 硬件与软件需求1.2 环境配置二、核心功能实现2.1 短信监听与获取2.

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

Java使用多线程处理未知任务数的方案介绍

《Java使用多线程处理未知任务数的方案介绍》这篇文章主要为大家详细介绍了Java如何使用多线程实现处理未知任务数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 知道任务个数,你可以定义好线程数规则,生成线程数去跑代码说明:1.虚拟线程池:使用 Executors.newVir

一文带你深入了解Python中的GeneratorExit异常处理

《一文带你深入了解Python中的GeneratorExit异常处理》GeneratorExit是Python内置的异常,当生成器或协程被强制关闭时,Python解释器会向其发送这个异常,下面我们来看... 目录GeneratorExit:协程世界的死亡通知书什么是GeneratorExit实际中的问题案例

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

Gin框架中的GET和POST表单处理的实现

《Gin框架中的GET和POST表单处理的实现》Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.For... 目录一、GET表单处理二、POST表单处理1. 使用c.PostForm获取表单字段:2. 绑定到结

mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespace id不一致处理

《mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespaceid不一致处理》文章描述了公司服务器断电后数据库故障的过程,作者通过查看错误日志、重新初始化数据目录、恢复备... 周末突然接到一位一年多没联系的妹妹打来电话,“刘哥,快来救救我”,我脑海瞬间冒出妙瓦底,电信火苲马扁.