假设我有2个收藏品" PlanSubscriptions "和" ClientActivations "。我在两个集合上连续插入。
后者取决于前一个,如果任何事务失败,那么整个操作必须回滚。
如何在Meteor 1.4中实现这一目标?
答案 0 :(得分:3)
由于MongoDB不支持原子性,因此您必须使用Method Chaining进行管理。
您可以编写一个方法,例如transaction
,您可以在其中调用PlanSubscriptions.insert(data, callback)
。然后在回调函数中,如果第一次插入成功则调用ClientActivations.insert(data, callback1)
,如果第二次插入成功,则调用callback1
返回truthy,否则为falsy。如果第一次插入返回错误,则您不需要执行任何操作,但如果第二次插入返回错误,则删除第一次收集中插入的ID。
我可以建议以下结构:
'transaction'(){
PlanSubscriptions.insert(data, (error, result)=>{
if(result){
// result contains the _id
let id_plan = result;
ClientActivations.insert(data, (error, result)=>{
if(result){
// result contains the _id
return true;
}
else if(error){
PlanSubscriptions.remove(id_plan);
return false;
}
})
}
else if(error){
return false;
}
})
}
答案 1 :(得分:0)
在Meteor中无法做到这一点,因为mongodb不是符合ACID标准的数据库。它具有单文档更新原子性,但不是多文档更新,这是两个集合的情况。 来自mongo文档:
当单个写入操作修改多个文档时,每个文档的修改都是原子的,但整个操作不是原子的,其他操作可能会交错。
可以使用一种隔离多文档更新可见性的方法,但这可能不是您需要的。
使用$ isolated运算符,一旦写入操作修改第一个文档,影响多个文档的写入操作可以防止其他进程交错。这可确保在写入操作完成或错误输出之前,任何客户端都不会看到更改。 隔离写操作不提供“全有或全无”原子性。也就是说,写入操作期间的错误不会回滚错误之前的所有更改。
但是,有几个库试图在应用级别解决问题。我建议您查看fawn
在您的情况下,如果您有两个依赖集合,则可以利用两阶段提交技术。在此处阅读更多相关信息:two-phase-commits
答案 2 :(得分:0)
我自己想通了。
我添加了一个包babrahams:transactions
在服务器端Meteor Method调用中,我调用了由包全局公开的tx
对象。整个服务器端Meteor.method({})
如下所示。
import { Meteor } from 'meteor/meteor';
import {PlanSubscriptions} from '/imports/api/plansubscriptions/plansubscriptions.js';
import {ClientActivations} from '/imports/api/clientactivation/clientactivations.js';
Meteor.methods({
'createClientSubscription' (subscriptionData, clientActivationData) {
var txid;
try {
txid = tx.start("Adding Subscription to our database");
PlanSubscriptions.insert(subscriptionData, {tx: true})
ClientActivations.insert(activation, {tx: true});
tx.commit();
return true;
} catch(e){
tx.undo(txid);
}
return false;
}
});
对于我添加{tx : true}
的每个插入内容,这使其成为交易的一部分。
服务器控制台输出:
I20170523-18:43:23.544(5.5)? Started "Adding Subscription to our database" with
transaction_id: vdJQvFgtyZuWcinyF
I20170523-18:43:23.547(5.5)? Pushed insert command to stack: vdJQvFgtyZuWcinyF
I20170523-18:43:23.549(5.5)? Pushed insert command to stack: vdJQvFgtyZuWcinyF
I20170523-18:43:23.551(5.5)? Beginning commit with transaction_id: vdJQvFgtyZuWcinyF
I20170523-18:43:23.655(5.5)? Executed insert
I20170523-18:43:23.666(5.5)? Executed insert
I20170523-18:43:23.698(5.5)? Commit reset transaction manager to clean state
有关详细信息,您可以转到链接:https://github.com/JackAdams/meteor-transactions
注意:我正在使用Meteor 1.4.4.2