Transactions事务

Sequelize supports two ways of using transactions:

Sequelize支持两种使用transactions的方法

  • One which will automatically commit or rollback the transaction based on the result of a promise chain and, (if enabled) pass the transaction to all calls within the callback一是基于promise链的结果去自动提交或回滚事务,(如果可以)并在回调中传递事务给所有调用
  • And one which leaves committing, rolling back and passing the transaction to the user.另一个则放弃提交、回滚和传递事务给用户

The key difference is that the managed transaction uses a callback that expects a promise to be returned to it while the unmanaged transaction returns a promise.

主要的不同在管理事务使用了promise被返回给它的回调,然而非管理交易也返回promise

Managed transaction (auto-callback)管理事务

Managed transactions handle committing or rolling back the transaction automagically. You start a managed transaction by passing a callback to sequelize.transaction.

管理事务将自动处理提交或回滚事务。你通过传递回调给sequelize.transaction来开始一个管理事务。

Notice how the callback passed to transaction returns a promise chain, and does not explicitly call t.commit() nor t.rollback(). If all promises in the returned chain are resolved successfully the transaction is committed. If one or several of the promises are rejected, the transaction is rolled back.

注意,回调怎么被传给事务将返回一个promise链,并不显式地调用 t.commit()t.rollback()。如果在返回链中的所有的promise都成功解决,事务将被提交。如果一个或一些promise被拒绝,事务将回滚。

return sequelize.transaction(function (t) {

  // chain all your queries here. make sure you return them.
return User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
}, {transaction: t}).then(function (user) {
return user.setShooter({
firstName: 'John',
lastName: 'Boothe'
}, {transaction: t});
}); }).then(function (result) {
// Transaction has been committed
// result is whatever the result of the promise chain returned to the transaction callback
}).catch(function (err) {
// Transaction has been rolled back
// err is whatever rejected the promise chain returned to the transaction callback
});

Throw errors to rollback抛出错误给回滚

When using the managed transaction you should never commit or rollback the transaction manually. If all queries are successful, but you still want to rollback the transaction (for example because of a validation failure) you should throw an error to break and reject the chain:

当使用管理事务时,你绝不应该手动提交或回滚事务。如果所有的查询都成功了,但是你仍然想要回滚事务(比如因为验证失败),你应该抛出一个错误去停止事务,并拒绝加入链中:

return sequelize.transaction(function (t) {
return User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
}, {transaction: t}).then(function (user) {
// Woops, the query was successful but we still want to roll back!
throw new Error();
});
});

Automatically pass transactions to all queries自动传递事务给所有查询

In the examples above, the transaction is still manually passed, by passing { transaction: t } as the second argument. To automatically pass the transaction to all queries you must install the continuation local storage(CLS) module and instantiate a namespace in your own code:

在上面的例子中,事务都是手动传递,通过传递{ transaction: t }作为第二变量。为了自动传递事务给所有查询,你一定要安装continuation local storage(CLS) 模块并在你的代码中实例化一个命名空间

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

To enable CLS you must tell sequelize which namespace to use by using a static method of the sequelize constructor:

为了使用CLS,你一定要通过sequelize构造函数的静态方法告诉sequelize使用的是那个命名空间:

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

Notice, that the useCLS() method is on the constructor, not on an instance of sequelize. This means that all instances will share the same namespace, and that CLS is all-or-nothing - you cannot enable it only for some instances.

注意,useCLS()方法是在构造函数中,而不是在sequelize中的。这意味着所有实例都可以共享这个命名空间,CLS是all-or-nothing的-你不可能只能在一些实例中使用它

CLS works like a thread-local storage for callbacks. What this means in practice is that different callback chains can access local variables by using the CLS namespace. When CLS is enabled sequelize will set the transactionproperty on the namespace when a new transaction is created. Since variables set within a callback chain are private to that chain several concurrent transactions can exist at the same time:

CLS像回调的本地线程存储一样工作。这意味着在实际中,当事务创建时不同的回调链能够通过CLS命名空间调用本地变量。因此回调链中的变量集对于该链都是私有的,多个并发事务可以同时存在;

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

In most case you won't need to access namespace.get('transaction') directly, since all queries will automatically look for a transaction on the namespace:

在更多情况下,我们不需要直接访问namespace.get('transaction'),因此所有查询将自动在命名空间中查找事务

sequelize.transaction(function (t1) {
// With CLS enabled, the user will be created inside the transaction
return User.create({ name: 'Alice' });
});

After you've used Sequelize.useCLS() all promises returned from sequelize will be patched to maintain CLS context. CLS is a complicated subject - more details in the docs for cls-bluebird, the patch used to make bluebird promises work with CLS.

在你使用 Sequelize.useCLS()之后,所有从sequelize中返回的promises将被修补去保持CLS上下文。CLS是复杂的主题-更多细节在文档cls-bluebird

Note: _CLS only supports async/await, at the moment, when using cls-hooked package. Although, cls-hookedrelies on experimental API async_hooks_

Concurrent/Partial transactions并发/局部事务

You can have concurrent transactions within a sequence of queries or have some of them excluded from any transactions. Use the {transaction: } option to control which transaction a query belong to:

在一系列查询中你可以有并发事务或一部分被事务排除

Warning: SQLite does not support more than one transaction at the same time.

SQLite不支持一次超过一个事务

Without CLS enabled

sequelize.transaction(function (t1) {
return sequelize.transaction(function (t2) {
// With CLS enable, queries here will by default use t2
// Pass in the `transaction` option to define/alter the transaction they belong to.
return Promise.all([
User.create({ name: 'Bob' }, { transaction: null }),
User.create({ name: 'Mallory' }, { transaction: t1 }),
User.create({ name: 'John' }) // this would default to t2
]);
});
});

Isolation levels

The possible isolations levels to use when starting a transaction:

在开始事务是可能的隔离级别:

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"

By default, sequelize uses the isolation level of the database. If you want to use a different isolation level, pass in the desired level as the first argument:

默认sequelize使用数据库的隔离级别。如果你想要使用不同的隔离级别,传递你心仪的级别作为第一变量

return sequelize.transaction({
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE
}, function (t) { // your transactions });

Note: The SET ISOLATION LEVEL queries are not logged in case of MSSQL as the specified isolationLevel is passed directly to tedious

Unmanaged transaction (then-callback)非管理事务

Unmanaged transactions force you to manually rollback or commit the transaction. If you don't do that, the transaction will hang until it times out. To start an unmanaged transaction, call sequelize.transaction()without a callback (you can still pass an options object) and call then on the returned promise. Notice that commit() and rollback() returns a promise.

非管理事务强迫你手动地回滚或提交事务。如果你不想这么做,事务将被挂起直至超时。为了开始非管理事务,调用没有回调的sequelize.transaction()(你还是可以传递选项options对象的)并在返回的promise中调用then。注意 commit()rollback()都返回promise

return sequelize.transaction().then(function (t) {
return User.create({
firstName: 'Bart',
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

The transaction method can be called with an options object as the first argument, that allows the configuration of the transaction.

事务方法可以带着options对象作为第一参数来被调用,options允许事务的配置

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

The following options (with their default values) are available:

下面的options(带着默认值)是可用的:

{
autocommit: true,
isolationLevel: 'REPEATABLE_READ',
deferrable: 'NOT DEFERRABLE' // implicit default of postgres
}

The isolationLevel can either be set globally when initializing the Sequelize instance or locally for every transaction:

当初始化Sequelize示例时,对每个事务isolationLevel要么被设置为全局的,要么是局部的

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

The deferrable option triggers an additional query after the transaction start that optionally set the constraint checks to be deferred or immediate. Please note that this is only supported in PostgreSQL.

Sequelize-nodejs-8-Transactions的更多相关文章

  1. 【前端】nodejs的ORM框架sequelize的工厂化

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/sequelize_factory.html 一.什么是sequelize nodejs的后台在操作数据库的时候,需 ...

  2. nodejs项目mysql使用sequelize支持存储emoji

    nodejs项目mysql使用sequelize支持存储emoji 本篇主要记录nodejs项目阿里云mysql如何支持存储emoji表情. 因由 最近项目遇到用户在文本输入emoji进行存储的时候导 ...

  3. koa2+log4js+sequelize搭建的nodejs服务

    主要参考http://www.jianshu.com/p/6b816c609669这篇文章 npm安装使用国内taobao镜像,速度更快些 npm --registry https://registr ...

  4. 从 moment -> nodejs -> sequelize -> postgres,你都得设置好时区

    背景 最近在做报表统计,因为 sequelize 的时区配置没加导致了统计数字对不上的问题. 问:大家都知道时区,但是你清楚 UTC 和 GMT 的区别吗? 答:UTC 是我们现在用的时间标准,GMT ...

  5. nodejs sequelize 对应数据库操作符的定义

    const Op = Sequelize.Op [Op.and]: {a: } // 且 (a = 5) [Op.or]: [{a: }, {a: }] // (a = 5 或 a = 6) [Op. ...

  6. postgresql on centos (sequelize+pg+nodejs):Failed to find PostgresSQL server.Pleast double check your settings

    公司的一个项目,使用的nodejs做服务端,数据库是postgresql,在本地时一切ok,放在centos时,postgresql配置ok,可以远程访问,但是nodejs在centos启动时,就会报 ...

  7. 项目总结,彻底掌握NodeJS中如何使用Sequelize

    前言 sequelize是什么? sequelize是基于NodeJs的ORM框架,它适用于不同的数据库,如:Postgres.MySQL.SQLite.MariaDB,我们可以通过sequelize ...

  8. 基于Nodejs的sequelize操纵数据库

    ## 使用基于ORM架构的sequelize操纵数据库 ### 1.技术背景 ```Sequelize是一个基于promise的关系型数据库ORM框架,*********************技术文 ...

  9. Nodejs ORM框架Sequelize快速入门

    Nodejs ORM框架Sequelize快速入门 什么是ORM? 简单的讲就是对SQL查询语句的封装,让我们可以用OOP的方式操作数据库,优雅的生成安全.可维护的SQL代码.直观上,是一种Model ...

  10. nodejs+sequelize操作mysql数据库

    前言: 本人对mysql不是很熟悉,只会命令行的简单增删改查.有些观点可能不到位请谅解. sequelize是针对node.js和io.js开发的基于ORM的框架,它支持的数据库包括:PostgreS ...

随机推荐

  1. Linux学习6-Linux常用命令(1)

    1.命令格式:命令 [-选项] [参数]     例如:ls -la /etc     说明: 1)个别命令使用不遵循此格式 2)当有多个选项时,可以写在一起 3)简化选项与完整选项 (-a等于 -- ...

  2. Python逐行读取文件内容

    更详细的文件按行读取操作可以参考:http://www.cnblogs.com/xuxn/archive/2011/07/27/read-a-file-with-python.html 一行一行得从文 ...

  3. problem-solving-with-algorithms-and-data-structure-usingpython(使用python解决算法和数据结构) -- 算法分析

    1. 计算前n个整数的和 def sumOfN(n): theSum = 0 for i in range(1,n+1): theSum += i return theSum print(sumOfN ...

  4. 连接数据库 JDBC、DBCP、JNDI

    一.JDBC package com.direct.util; import java.sql.Connection; import java.sql.DriverManager; import ja ...

  5. 百度 echarts K线图使用

    看个效果图先 首先在需要插入图例的HTML中嵌入 <div id="main" style="height:400px"></div> ...

  6. 前端模块化工具--webpack学习心得

    话说前头 webpack前段时间有听说一下,现在已经到了3.x的版本,自己没去接触.因为之前使用gulp来作为自己的项目构建工具.现在感觉gulp使用的趋势在减少.现在这段时间去接触了webpack, ...

  7. 网鼎杯 pwn 记录

    题目位置 https://gitee.com/hac425/blog_data/tree/master/wdb babyheap 通过分配和释放构建 2 个 fastbin 链 利用 show 功能, ...

  8. 润乾V4报表批量打印

     背景说明 在应用中,经常遇到,批量打印的需求,批量打印,顾名思义,就是点击一次打印按钮,能打印多张报表. 下面,我们来介绍一下怎么样实现批量打印的 应用举例: Jsp代码 <% //rep ...

  9. 【转】虚拟机安装Ubuntu的上网设置(有线网络和无线网络)

    虚拟机下ubuntu共享方式上网: 一. 有线网络 在有线网络的条件下,vmware的安装非常简单,上网方式几乎不用怎么设置(默认NAT模式)    如果默认情况下不能上网,则按以下步骤尝试: *** ...

  10. mysql使用笔记(网易Mysql实用手册)---1

    1帮助使用 1.1按层次查看帮助 1 当不知道帮助可提供什么时,可通过MySQL内置帮助文档,一层层往下看. 命令: mysql> ? contents ? 等效help,该文档涵盖了数据库操作 ...