跨 DAL 操作的事务 + Web 服务调用 +记录
我的问题是,我至少在一种情况下还调用 Web 服务,记录到数据库表。下面是一些伪代码,可能有助于让事情变得更清楚:
customer = batchRefundToProcess.RefundCustomer;
//Validate everything
if (ValidateRefund(batchRefundToProcess) == false)
{
refund.RefundStatusId = (int)REFUNDSTATUSES.RefundDenied;
refund.ReviewedBy = displayUserName;
refund.Update();
return false;
}
//get this customer's payments
List<RefundTran> trans = customer.ARTransactions;
refund.RefundStatusId = (int)REFUNDSTATUSES.RefundInProcess;
refund.ReviewDate = DateTime.Now;
refund.ReviewedBy = displayUserName;
refund.Update();
List<RefundTran> paperTransactions = new List<RefundTran>();
foreach (RefundTran transaction in trans)
{
if (customer.Balance < 0) //balance is negative if we owe them money
{
//processtransaction has the following side effects:
//1. refund detail is created for the tran
//2. customer is billed for the refunded amount, web service is called
var paperTransaction = processTransaction(customer, transaction, refund);
if (paperTransaction != null) //this transaction qualifies for a paper check for one reason or another
{
paperTransactions.Add(paperTransaction);
}
}
}
//get total amount
//basically, the sum total of all their paper check transactions plus whatever's left on their balance, if anything
decimal paperCheckAmount = paperTransactions.Sum(pt => pt.Amount) - customer.Balance;
if (paperTransactions.Count > 0)
{
//cut a check for all the transactions together
AddLineToFile(customer, paperCheckAmount, paperTransactions.First(), REFUNDFILETYPE.ElectronicCheck, refund.RefundId);
}
refund.RefundStatusId = (int)REFUNDSTATUSES.RefundApproved;
refund.ReviewedBy = displayUserName;
refund.Update();
} //end using block
return true;
其中有 Web 服务调用,以及一些数据库日志记录。我知道没有什么神奇的方法可以“撤消”对外部供应商的 Web 服务调用,但是如果失败,如何防止数据库日志记录随事务一起回滚?如果我已经进行了网络服务调用,我应该做什么?我是不是把这件事搞得太难了?我不想向客户开具账单,然后却未能给他们开一张支票,或者更糟糕(在我的组织看来),给他们开一张支票,但未能向他们的帐户开具账单!
I've already looked here and found some great advice on managing transactions.
My problem is that I'm also calling a web service in at least one case, logging to a database table. Here's some psuedo-code that might help make things more clear:
customer = batchRefundToProcess.RefundCustomer;
//Validate everything
if (ValidateRefund(batchRefundToProcess) == false)
{
refund.RefundStatusId = (int)REFUNDSTATUSES.RefundDenied;
refund.ReviewedBy = displayUserName;
refund.Update();
return false;
}
//get this customer's payments
List<RefundTran> trans = customer.ARTransactions;
refund.RefundStatusId = (int)REFUNDSTATUSES.RefundInProcess;
refund.ReviewDate = DateTime.Now;
refund.ReviewedBy = displayUserName;
refund.Update();
List<RefundTran> paperTransactions = new List<RefundTran>();
foreach (RefundTran transaction in trans)
{
if (customer.Balance < 0) //balance is negative if we owe them money
{
//processtransaction has the following side effects:
//1. refund detail is created for the tran
//2. customer is billed for the refunded amount, web service is called
var paperTransaction = processTransaction(customer, transaction, refund);
if (paperTransaction != null) //this transaction qualifies for a paper check for one reason or another
{
paperTransactions.Add(paperTransaction);
}
}
}
//get total amount
//basically, the sum total of all their paper check transactions plus whatever's left on their balance, if anything
decimal paperCheckAmount = paperTransactions.Sum(pt => pt.Amount) - customer.Balance;
if (paperTransactions.Count > 0)
{
//cut a check for all the transactions together
AddLineToFile(customer, paperCheckAmount, paperTransactions.First(), REFUNDFILETYPE.ElectronicCheck, refund.RefundId);
}
refund.RefundStatusId = (int)REFUNDSTATUSES.RefundApproved;
refund.ReviewedBy = displayUserName;
refund.Update();
} //end using block
return true;
There are webservice calls in there, and some database logging. I know there's no magic way to "undo" a webservice call to an outside vendor, but how do I keep the database logging from rolling back along with the transaction if it fails? What should I do in the event that I've already made the webservice call? Am I making this too hard? I don't want to bill a customer and then fail on cutting them a check, or worse (in my organization's opinion), cut them a check but fail on billing their account!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我知道这有点晚了,但实现这样的目标的唯一方法是使用 NServiceBus 之类的东西。
看看 http://andreasohlund.net/2009/08/ 24/使用-nservicebus实现一致性/
它提供了类似要求的示例
I know this is a bit late but the only way you would achieve something like this is using something like NServiceBus.
Have a look at http://andreasohlund.net/2009/08/24/achieving-consistency-using-nservicebus/
it provides an example of a similar requirement