我正在使用ServiceStack.net开发服务器应用程序。数据库通过EntityFramwork访问。现在我希望有一个Ambient Transaction,如果没有错误/异常会自动提交,否则应该丢弃更改。
我还没有找到一些尚未找到的东西,或者我是否需要自己推出?
如果我必须自己动手,我应该怎么做?首先想到的是请求和响应过滤器。
答案 0 :(得分:2)
我已经使用请求和响应过滤器来设置环境事务(在我的情况下实际上是一个NHibernate会话,但这是一个类似的想法)。我们通过在AppHost的RequestFilters
方法中添加ResponseFilters
和Configure
集合来完成此操作。
我们还需要区分在成功时提交交易和在任何错误上回滚/清算交易:
// 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);
};
答案 1 :(得分:1)
@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();
}
});
}