当前位置: 首页 > 后端技术 > Node.js

Sequelize中文文档v4-Transactions-Transaction

时间:2023-04-03 13:26:04 Node.js

Transactions-Transaction本系列文章的应用示例已发布在GitHub上:sequelize-docs-Zh-CN。您可以Fork以帮助改进或Star以关注更新。WelcomeStar.Sequelize支持两种使用Transactional方法:一种将根据承诺链的结果自动提交或回滚事务,(如果启用)通过回调将事务传递给所有调用,另一种保留提交、回滚和传递交易给用户。主要区别在于托管事务使用回调,而非托管事务期望返回承诺的承诺。托管事务(自动回调)托管事务自动处理提交或回滚事务。您可以通过将回调传递给sequelize.transaction来启动托管事务。注意传递给事务的回调是否是一个承诺链并且没有显式调用t.commit()或t.rollback()。如果返回链中的所有承诺都成功解决,则交易被提交。如果一个或多个承诺被拒绝,交易将被回滚。returnsequelize.transaction(function(t){//在此处链接所有查询。确保返回它们。返回User.create({firstName:'Abraham',lastName:'Lincoln'},{transaction:t}).then(function(user){returnuser.setShooter({firstName:'John',lastName:'Boothe'},{transaction:t});});}).then(function(result){//事务已经提交//result是返回给事务回调的promise链的结果}).catch(function(err){//事务已被回滚//err是拒绝返回给事务回调的promise链的错误});抛出错误回滚使用托管事务时,您永远不应该手动提交或回滚事务。如果所有查询都成功,但你仍然想回滚事务(例如,因为验证失败),你应该抛出一个错误来中断并拒绝链接:returnsequelize.transaction(function(t){returnUser.create({firstName:'Abraham',lastName:'Lincoln'},{transaction:t}).then(function(user){//查询成功,但我们仍要回滚!thrownewError();});});自动将事务传递给所有查询在上面的示例中,事务仍然是手动传递的,方法是传递{transaction:t}作为第二个参数。要自动将事务传递给所有查询,您必须安装延续本地存储(CLS)模块,并在您自己的代码中实例化一个命名空间:constcls=require('continuation-local-storage'),namespace=cls.createNamespace('我自己的命名空间');要启用CLS,您必须使用sequelize构造函数的静态方法告诉Sequelize使用哪个命名空间:constSequelize=require('sequelize');Sequelize.useCLS(命名空间);newSequelize(....);请注意,useCLS()方法在构造函数上,而不是在sequelize的实例上。这意味着所有实例将共享同一个命名空间,而CLS是全有或全无——您不能只在某些实例中启用它。CLS的工作方式类似于用于回调的线程本地存储。这在实践中意味着不同的回调链可以通过使用CLS命名空间访问局部变量。启用CLS后,Sequelize将在创建新事务时在命名空间上设置事务属性。由于回调链中设置的变量是链私有的,因此可以同时存在多个并发事务: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时,用户将在交易中创建returnUser.create({name:'Alice'});});在使用Sequelize.useCLS()之后,从sequelize返回的所有承诺都将被修补以维护CLS上下文。CLS是一个复杂的主题——cls-bluebird的文档中有更多详细信息,以及使bluebirdpromise与CLS一起工作的补丁。并行/部分事务您可以在一系列查询中执行并发事务,或从任何事务中排除某些事务。使用{transaction:}选项控制查询所属的事务:disableCLSsequelize.transaction(function(t1){returnsequelize.transaction(function(t2){//启用CLS,这里的查询会默认使用t2//通过`transaction`选项来定义/更改它们所属的事务。返回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//"READUNCOMMITTED"Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED//"READCOMMITTED"Sequelize.Transaction.ISOLATION_LEVELS.REPEATABLE_READ//"REPEATABLEREAD"Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE//"SERIALIZABLE"默认情况下,sequelize使用数据库的隔离级别。如果你想使用不同的隔离级别,将所需的级别作为第一个参数传递:注意:在MSSQL的情况下,SETISOLATIONLEVEL查询不被记录,指定的isolationLevel直接传递给繁琐的非托管事务(then-callback)。非托管事务强制您手动回滚或提交事务。如果不这样做,事务将挂起直到超时。要启动非托管事务,请在没有回调的情况下调用sequelize.transaction()(您仍然可以传递一个选项对象),然后调用返回的承诺。注意commit()和rollback()返回一个承诺。returnsequelize.transaction().then(function(t){returnUser.create({firstName:'Homer',lastName:'Simpson'},{transaction:t}).then(function(user){返回用户。addSibling({firstName:'Lisa',lastName:'Simpson'},{transaction:t});}).then(function(){returnt.commit();}).catch(function(err){返回t.rollback();});});parameter可以使用选项对象作为第一个参数来调用交易方法,这允许配置交易。returnsequelize.transaction({/*选项*/});以下选项(具有默认值)可用:{autocommit:true,isolationLevel:'REPEATABLE_READ',deferrable:'NOTDEFERRABLE'//Sequelize中postgres的默认设置}当实例或每个本地事务初始化时,isolationLevel可以全局设置://GlobalnewSequelize('db','user','pw',{isolationLevel:Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE});//Localsequelize.事务({隔离级别:Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE});可延迟选项在事务开始后触发额外的查询,可选择将约束检查设置为延迟或立即。请注意,这仅在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文档中的确定签名的方法。如果本文对您有帮助,请在下方点赞或starGitHub:sequelize-docs-Zh-CN支持,谢谢。