【问题标题】:Howto Ambient Transaction in ServiceStack.net如何在 ServiceStack.net 中环境事务
【发布时间】:2013-07-16 09:03:17
【问题描述】:
我正在使用 ServiceStack.net 开发一个服务器应用程序。通过 EntityFramwork 访问数据库。现在我想要一个环境事务,如果没有错误/异常,它会自动提交,否则应该丢弃更改。
有什么开箱即用的东西我还没有找到,还是我需要自己推出?
如果我必须自己滚动,我应该怎么做?首先想到的是请求和响应过滤器。
【问题讨论】:
标签:
.net
entity-framework
transactions
servicestack
【解决方案1】:
我使用请求和响应过滤器来设置环境事务(在我的例子中实际上是一个 NHibernate 会话,但这是一个类似的想法)。为此,我们在 AppHost 的 Configure 方法中添加了 RequestFilters 和 ResponseFilters 集合。
我们还需要区分成功提交事务和遇到任何错误时回滚/清除事务:
// normally: commit the transaction
ResponseFilters.Add((req, res, dto) => DbConnectionUtility.CleanupTransactionsAndConnections(req.RawUrl));
// rollback if unhandled exception in a service method
ServiceExceptionHandler = (request, exception) =>
{
DbConnectionUtility.ClearSessions();
// run the default code that sends a nicely serialized error response
return DtoUtils.HandleException(this, request, exception);
};
// rollback if unhandled exception outside of service (e.g. in a filter)
var defaultExceptionHandler = ExceptionHandler;
ExceptionHandler = (httpReq, httpRes, operationName, ex) =>
{
DbConnectionUtility.ClearSessions();
// run the default code that sends a nicely serialized error response
defaultExceptionHandler(httpReq, httpRes, operationName, ex);
};
【解决方案2】:
@esker 感谢您为我指明正确的方向
由于TransactionScope 默认回滚,如果Complete() 未被调用,我不需要为ServiceExceptionHandler 和ExceptionHandler 附加处理程序
我当前的解决方案在 AppHost 文件中如下所示:
public void ConfigureFilters(Container container)
{
RequestFilters.Add(
(req, res, dto) =>
req.Items.Add("transaction", new TransactionScope(TransactionScopeOption.RequiresNew)));
ResponseFilters.Add((req, res, dto) =>
{
TransactionScope transaction = null;
var error = dto as HttpError;
try
{
transaction = req.Items["transaction"] as TransactionScope;
if (error == null)
{
container.Resolve<TierDbEntitiesContainer>().SaveChanges();
if (transaction == null)
throw new AmbientTransactionException("Transaction not found.");
transaction.Complete();
}
}
finally
{
if (transaction != null)
transaction.Dispose();
}
});
}