【问题标题】: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 方法中添加了 RequestFiltersResponseFilters 集合。

    我们还需要区分成功提交事务和遇到任何错误时回滚/清除事务:

    // 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() 未被调用,我不需要为ServiceExceptionHandlerExceptionHandler 附加处理程序

      我当前的解决方案在 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();
                  }
              });
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-02
        • 1970-01-01
        • 2015-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-26
        相关资源
        最近更新 更多