【发布时间】:2019-12-08 13:50:12
【问题描述】:
(警告:这也在https://forums.fsharp.org/t/asyncresult-and-handling-rollback/928上发布)
尝试在 F# 中实现 2PC Transaction Like 工作流(请参阅 http://learnmongodbthehardway.com/article/transactions/)并遇到计算表达式(例如 asyncResult)和回滚问题。
如果你有以下伪代码:
let rollbackWorkflow parX parY =
… here calling rollbackService1 and rollbackService2
let executeWorkflow par1 par2 par3 =
asyncResult {
let! result1 = callService1 x y z
let! result2 = callService2 x2 y2 z2
}
如果 result1 和/或 result2 为错误,我如何检查 executeWorkflow,然后调用 rollbackWorkflow 函数?我应该更改 callService1 和 callService2 以引发异常,而不是在预期的错误情况下(资金不足、超出限制)也返回结果,还是应该使用诸如 teeError 之类的函数?任何建议都非常感谢!
附:这是我最终想要实现的:
function executeTransaction(from, to, amount) {
var transactionId = ObjectId();
transactions.insert({
_id: transactionId,
source: from,
destination: to,
amount: amount,
state: “initial”
});
var result = transactions.updateOne(
{ _id: transactionId },
{ $set: { state: “pending” } }
);
if (result.modifiedCount == 0) {
cancel(transactionId);
throw Error(“Failed to move transaction " + transactionId + " to pending”);
}
// Set up pending debit
result = accounts.updateOne({
name: from,
pendingTransactions: { $ne: transactionId },
balance: { $gte: amount }
}, {
$inc: { balance: -amount },
$push: { pendingTransactions: transactionId }
});
if (result.modifiedCount == 0) {
rollback(from, to, amount, transactionId);
throw Error(“Failed to debit " + from + " account”);
}
// Setup pending credit
result = accounts.updateOne({
name: to,
pendingTransactions: { $ne: transactionId }
}, {
$inc: { balance: amount },
$push: { pendingTransactions: transactionId }
});
if (result.modifiedCount == 0) {
rollback(from, to, amount, transactionId);
throw Error(“Failed to credit " + to + " account”);
}
// Update transaction to committed
result = transactions.updateOne(
{ _id: transactionId },
{ $set: { state: “committed” } }
);
if (result.modifiedCount == 0) {
rollback(from, to, amount, transactionId);
throw Error(“Failed to move transaction " + transactionId + " to committed”);
}
// Attempt cleanup
cleanup(from, to, transactionId);
}
executeTransaction(“Joe Moneylender”, “Peter Bum”, 100);
【问题讨论】:
-
首先,你的
asyncResult是在哪里实现的?
标签: f# expression computation