在 NodeJS 中利用 bookshelf.js 进行事务管理

作者:link

术语事务指的是构成单一逻辑工作单元的操作的集合。比如:将钱从一个账户转到另一个账户就是一个事务,该事务包括分别针对每个账户的两个更新。

英文中transaction又是交易的意思,我想应该是因为事务(transaction)管理的场景首先是出现在利用银行账户进行交易(transaction)的过程中,所以计算机科学家们把数据库的这一特性称为事务(transaction)。

事务有以下几个属性:

  • 原子性(atomicity):事务的所有操作在数据库中要么全部正确反映出来,要么完全不反映。
  • 一致性(consistency):隔离执行事务时(换言之,在没有其他事务并发执行的情况下)保持数据库的一致性。
  • 隔离性(isolation): 尽管多个事务可能并发执行,但系统保证,对于任何一对事务T<sub>i</sub>和T<sub>j</sub>,在T<sub>i</sub>看来,T<sub>j</sub>或者在T<sub>i</sub>开始之前已经执行完成,或者在T<sub>i</sub>完成之后开始执行。因此,每一个事务都感觉不到系统中有其他事务在并发执行。
  • 持久性(durability):一旦事务执行成功,它对数据库的改变必须是永久的——即一个可能出现的系统故障不应该导致数据库忽略成功完成的事务。

这些性质通常成为ACID特性,这一缩写来自四条性质的首字母。

在NodeJS中我们可以借助ORM框架来方便地实现事务操作,这里用bookshelf.js来举例说明。

bookshelf.js是一个基于knex.js的Node.js ORM框架,支持PostgreSQL,MySQL和SQLite3

简单来说,bookself是一个优秀的代码库,它易于阅读、理解、可扩展。它不强制你使用任何特定的校验scheme,而是提供灵活有效的关系或嵌套关系加载策略,一级类支持事务。它是一个精益的对象关系映射器(lean Object Relation Mapper),允许你使用原始的knex接口,因为当你需要自定义查询时,它有时并不能完全满足老一套的惯例。

bookshelf遵从和backbone.js一样棒的Models和Collections思想,使用相同的模式、命名惯例和哲学构建轻量、易于操控的ORM。如果你已经了解backbone,你就知道如何使用bookshelf.

bookshelf使用bluebird管理异步操作。

下面来演示如何使用bookshelf进行事务管理

model/db_config.json

{
  client: 'mysql',
  connection: {
    host     : '127.0.0.1',
	port     : 3306,
    user     : 'your_database_user',
    password : 'your_database_password',
    database : 'myapp_test',
    charset  : 'utf8'
  }
}

model/base.js

'use strict'

/**
 * init bookshelf connection
 * @type {[type]}
 */
let Bookshelf = null,
    dbConfig = require('./db_config');
module.exports = function() {
	"use strict";

	if (Bookshelf) {
		return Bookshelf;
	}

	var knex = require('knex')(dbConfig);

	Bookshelf = require('bookshelf')(knex);

	/**
     * This solves the circular module dependency problem created by Bookshelf models
     * in a previous commit #38d98bb4c33e91b636a3538bd546ebe7f5077328
     **/
	Bookshelf.plugin('registry');

	return Bookshelf;
};

model/users.js

'use strict'

const bookshelf = require('./base')();

// 一般情况下后台或者DBA的同学会帮我们把数据库和表建好,我们直接操作就好。所以我们只需要利用已有的表结构初始化一个ORM的实例来进行操作。
var Users = bookshelf.Model.extend({
    tableName: 'users'
});

module.exports = Users;

model/room.js

'use strict'

const bookshelf = require('./base')();

// 一般情况下后台或者DBA的同学会帮我们把数据库和表建好,我们直接操作就好。所以我们只需要利用已有的表结构初始化一个ORM的实例来进行操作。
var Room = bookshelf.Model.extend({
    tableName: 'room'
});

module.exports = Room;

controllers/transaction.js

'use strict'

const Bookshelf = require('../model/base')();
const Room = require('../model/room');
const Users = require('../model/users');

Bookshelf.transaction(function (t) {
    return Users.forge(data) // 需要存入users表的数据
    .save(null, { transacting: t })
    .then(function (users){
        return Room.forge({ userId: user.id }) // 将新增的user同时存入room表中
        .save(null, { transacting: t })
        .then(function (){
            return users; // 返回users表的model
        });
    })
}).then((users) => {
	// doSomething
}).catch((error) => {
	//handle error
})

关于bookshelf.js的更多信息可以参考他们的官网:http://bookshelfjs.org/

原文链接:http://ivweb.io/topic/56628e8bd91952db73b41f4f

原文链接:

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Linyb极客之路

20个【MySQL】经典面试题

一个6亿的表a,一个3亿的表b,通过外间tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记录。

1222
来自专栏james大数据架构

微软官方提供的用于监控MS SQL Server运行状况的工具及SQL语句

Microsoft SQL Server 2005 提供了一些工具来监控数据库。方法之一是动态管理视图。动态管理视图 (DMV) 和动态管理函数 (DMF) 返...

1947
来自专栏Java架构师历程

sql必会基础3

对于查询占主要的应用来说,索引显得尤为重要。很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致。如果不加索引的话,那么查...

842
来自专栏YoungGy

HIVE入门_2

HIVE 是数据仓库,本质上也是数据库。 数据仓库 概念 就是一个数据库。 数据仓库是一个面向主题的(商品的推荐系统内容是商品的信息)、集成的(分散型地...

2315
来自专栏JMCui

SQL优化二(SQL性能调优)

一·、前言:这篇博文内容非原创,是我们公司的架构师给我们做技术培训的时候讲的内容,我稍微整理了下,借花献佛。这篇博文只是做一个大概的科普介绍,毕竟SQL优化的知...

3546
来自专栏微信公众号:Java团长

Java面试中常问的数据库方面问题

B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接,是有序的

823
来自专栏Linyb极客之路

Java面试中常问的数据库方面问题

B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接,是有序的

843
来自专栏杨建荣的学习笔记

巧用parallel极速提升数据加载速度(r2第21天)

并行在平时工作中可能不是很注意,因为有时候即使设定了parallel 相关的hint,感觉性能也好不到哪去。这是我以前的感觉。 今天通过一个案例来分享一下通过p...

3286
来自专栏数据和云

一篇文章带你读懂 MySQL 和 InnoDB

原文地址 | http://draveness.me/mysql-innodb.html

1155
来自专栏Java后端生活

JDBC(八)批量处理

当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率

903

扫码关注云+社区