2012-04-29 77 views
0

我们有一个奇怪的情况发生在这里。我们已经建立了NuGet图库的本地安装(与http://Nuget.org相同的代码)。 IIS和数据库位于同一个框中。 IIS应用程序池已配置为在本地管理员的域用户下运行,并具有“作为服务登录的权限”权限。现在,当有人(后成功地登录)尝试并上传包,上传包裹业务需要年龄,并最终引发了“基础提供无法打开”的错误NuGet Gallery和EntityFramework抛出失败打开提供者错误

[TimeoutException: Transaction Timeout] 

[TransactionException: The operation is not valid for the state of the transaction.] 
    System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction) +53 
    System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification) +241 
    System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx) +273 
    System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction) +150 
    System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) +2647 
    System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +89 
    System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +6372062 
    System.Data.SqlClient.SqlConnection.Open() +300 
    System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +67 

[EntityException: The underlying provider failed on Open.] 
    System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +11109230 
    System.Data.EntityClient.EntityConnection.Open() +142 
    System.Data.Objects.ObjectContext.EnsureConnection() +97 
    System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal(String commandText, String entitySetName, MergeOption mergeOption, Object[] parameters) +109 
    System.Data.Objects.ObjectContext.ExecuteStoreQuery(String commandText, Object[] parameters) +87 
    System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(String sql, Object[] parameters) +118 
    System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable(String sql, Object[] parameters) +85 
    System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(Type elementType, String sql, Object[] parameters) +241 
    System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator() +34 
    System.Data.Entity.Internal.InternalSqlQuery`1.GetEnumerator() +28 
    System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +382 
    System.Linq.Enumerable.ToList(IEnumerable`1 source) +80 
    NuGetGallery.LuceneIndexingService.GetPackages(DbContext context, Nullable`1 dateTime) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Infrastructure\Lucene\LuceneIndexingService.cs:55 
    NuGetGallery.LuceneIndexingService.UpdateIndex() in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Infrastructure\Lucene\LuceneIndexingService.cs:32 
    NuGetGallery.PackageService.CreatePackage(IPackage nugetPackage, User currentUser) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Services\PackageService.cs:61 
    NuGetGallery.PackagesController.VerifyPackage(Nullable`1 listed) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Controllers\PackagesController.cs:503 
    lambda_method(Closure , ControllerBase , Object[]) +121 
    System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +248 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39 
    System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +125 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312 
    System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +691 
    System.Web.Mvc.Controller.ExecuteCore() +162 
    System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +305 
    System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62 
    System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375 

有趣的是,如果我切换IIS应用程序池,以在内置的“LocalSystem”帐户下运行,所有这些问题都会消失。我们想要使用的域用户已经临时设置为NuGetGallery数据库的数据库所有者,但它不起作用。

任何人都可以建议我们可能会在这里丢失什么设置/配置?

+0

当您的交易被提升为分布式交易时,这看起来像是个例外。我不知道解决问题的方式,或者这是否是由于未充分的许可,但首先我会尝试回答以下问题 - 您是否意识到您的交易正在提升为分布式交易(分布式交易通常会消耗大量的系统资源) ?如果是这样,是故意的吗?最后(或者可能是第一次)你使用Sql server 2005吗?在Sql server 2005中,如果您有多个连接到事务中的同一个Sql服务器,它将被升级。 – Pawel 2012-04-29 16:13:03

+0

谢谢帕维尔。我将通过代码来查看分布式事务是否正在进行。这是一个我们在这里使用的开源产品,因此对代码库不熟悉。使用的数据库是SQL Server 2008。请你让我知道如何发现分布式事务? – Nikhil 2012-04-29 17:21:12

回答

0

这是由于环境事务在代码内进行的。该代码依赖于TransactionScope类来管理各种事务,当它们嵌套时它们正在进入阻塞状态。如果有人尝试上传超过10MB大小的包,情况就会变得特别糟糕。一旦我们调整了盒子上的MSDTC,应用程序就开始表现得稍微正确。然而,它仍然在自己的事务中间歇性地陷入僵局,所以现在我们决定从包上传位中删除事务。

对于其他人谁进入这个问题,我会推荐这两种

  1. 注释掉TransactionScope的任何参考的

服务\ PackageService.cs(方法CreatePackage,48行)

using (var tx = new TransactionScope()) 
      { 
       using (var stream = nugetPackage.GetStream()) 
       { 
        UpdateIsLatest(packageRegistration); 
        packageRegistrationRepo.CommitChanges(); 
        packageFileSvc.SavePackageFile(package, stream); 
        tx.Complete(); 
       } 
      } 

而在控制器\ PackageController.cs方法VerifyPackage(布尔?上市)线501

using (var tx = new TransactionScope()) 
      { 

       package = packageSvc.CreatePackage(nugetPackage, currentUser); 
       packageSvc.PublishPackage(package.PackageRegistration.Id, package.Version); 
       if (listed.HasValue && listed.Value == false) 
        packageSvc.MarkPackageUnlisted(package); 
       uploadFileSvc.DeleteUploadFile(currentUser.Key); 
       tx.Complete(); 
      } 

2取消注释这些行,并按照这里提到http://blogs.msdn.com/b/dbrowne/archive/2010/05/21/using-new-transactionscope-considered-harmful.aspx

基本上创建一个TransactionScope它可以与SQL Server以及工作方法。在InfraStructureFolder中创建一个新类,将其称为TranscationUtils并将代码复制到那里。然后用块看起来像

using (var tx = new TransactionUtils.CreateTransactionScope()){ 

//cod here 
tx.Complete(); 
} 

然而,这第二种方法可能会导致这又涉及到你可以指定TransactionScope的默认超时另一台服务器错误。我们亲自决定采用方法1,并立即注释掉所有的TransactionScope参考资料。

相关问题