0

ここで奇妙な状況が発生しています。NuGet ギャラリー ( http://Nuget.orgと同じコード) のローカル インストールをセットアップしました。IIS と DB は同じボックスにあります。IIS アプリケーション プールは、ボックスのローカル管理者でもあり、「サービスとしてログオンする権利」を持つドメイン ユーザーの下で実行するように構成されています。誰かが (ログインに成功した後) パッケージをアップロードしようとすると、パッケージのアップロード ビジネスに時間がかかり、最終的に「基になるプロバイダーを開けませんでした」というエラーがスローされます。

  [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 データベースのデータベース所有者として一時的に設定されていますが、役に立ちません。

ここで欠けている可能性のある設定/構成を誰か提案できますか?

4

1 に答える 1

0

これは、コード内で行われているアンビエント トランザクションが原因でした。コードは、TransactionScope クラスに依存して、ネストされたときにジャム状態になったさまざまなトランザクションを管理していました。サイズが約 10MB を超えるパッケージを誰かがアップロードしようとすると、事態は特に悪化しました。ボックスの MSDTC を微調整すると、アプリケーションはわずかに適切に動作し始めました。ただし、それ自体のトランザクション内で断続的にデッドロックが発生していたため、現時点では、パッケージ アップロード ビットからトランザクションを削除することにしました。

この問題に遭遇した他の人には、これら2つのいずれかをお勧めします

  1. の TransactionScope への参照をコメントアウトします。

Services\PackageService.cs (メソッド CreatePackage、48 行目)

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

Controller\PackageController.cs メソッドの VerifyPackage(bool? Listed) 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

基本的に、SQL Server でうまく動作するトランザクション スコープを作成します。InfraStructureFolder に新しいクラスを作成し、TranscationUtils という名前を付けて、そこにコードをコピーします。次に、使用ブロックは次のようになります

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

//cod here
tx.Complete();
}

ただし、この 2 番目の方法では、TransactionScope に指定できるデフォルトのタイムアウトに関連する別のサーバー エラーが発生する可能性があります。個人的には、アプローチ 1 を採用し、すべての TransactionScope 参照をコメントアウトすることにしました。

于 2012-05-03T08:52:54.817 に答える