2012-05-14 87 views
2

如果我打開一個dbContext作爲全局變量,如下面的代碼所示,與每個函數中使用新的datacontext相比,它會導致連接池問題,並將其封裝在使用塊?這樣做linq會導致連接池問題

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using LoopinDeals.Helper; 

namespace LoopinDeals.Model 
{ 
    public class DealUsersRepository 
    { 
     private DataClassesDataContext DbContext = new DataClassesDataContext(); 

     public void AddUser(string Email, string Password) 
     { 
      DealUser deal = new DealUser() 
      { 
       Email = Email, 
       Password = Password, 
       EmailVerified = true, 
       LastLogin = DateTime.Now, 
       AccountCreated = DateTime.Now, 
       IsActive = true, 
       RegistrationMethod = RegistrationType.Normal.ToString(), 
       Subscribe = "true" 
      }; 

      DbContext.DealUsers.InsertOnSubmit(deal); 
      DbContext.SubmitChanges(); 
     } 

     public void AddSignUpUser(string Email, string City) 
     { 
      try 
      { 
       DealUser UserData = new DealUser() 
        { 
         Email = Email, 
         City = City, 
         IsActive = false, 
         LastLogin = DateTime.Now 
        }; 
       DbContext.DealUsers.InsertOnSubmit(UserData); 
      } 
      catch (Exception ex) 
      {    

      } 
     } 

     public void UpdateSignUpUser(string Email, string FirstName, string LastName, string Password, string Mobile, string City) 
     { 
      try 
      { 
       DealUser UserData = DbContext.DealUsers.Single(UD => UD.Email == Email); 
       UserData.FirstName = FirstName; 
       UserData.LastName = LastName; 
       UserData.Password = Password; 
       UserData.Mobile = Mobile; 
       UserData.City = City; 
       UserData.IsActive = true; 
       UserData.LastLogin = DateTime.Now; 
       DbContext.SubmitChanges(); 
      } 
      catch (Exception ex) 
      { 

      } 
     } 


    } 
} 

說明

請注意,我沒有寫這個代碼,它被外包。它崩潰與以下錯誤消息,我想弄清楚如何解決它。

Server Error in '/' Application. Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

Source Error:

[No relevant source lines]

Source File: c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\f44daa26\cce00cbd\App_Web_b21g2v5x.5.cs Line: 0

Stack Trace:

[InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.]
System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +6264689
System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +6265031
System.Data.SqlClient.SqlConnection.Open() +258
System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user) +65 System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe() +33 System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode() +32
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +63
System.Data.Linq.DataQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator() +45 LoopinDeals.Model.SiteDetails..ctor() +253 LoopinDeals.Admin.Default..ctor() +76
ASP.admin_default_aspx..ctor() in c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\f44daa26\cce00cbd\App_Web_b21g2v5x.5.cs:0
__ASP.FastObjectFactory_app_web_b21g2v5x.Create_ASP_admin_default_aspx() in c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\f44daa26\cce00cbd\App_Web_b21g2v5x.22.cs:0
System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp, Boolean noAssert) +138
System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath) +50 System.Web.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +425 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +263

我在這裏添加了SiteDetailsConstructor,是否有可能導致連接池問題?

public class SiteDetails 
    { 
     public DataClassesDataContext DbContext = new DataClassesDataContext(); 

     public SiteDetails() 
     { 
      var Details = from dtl in DbContext.SiteSettings 
          select dtl; 

      foreach (var item in Details) 
      { 
       MetaIndexKeyword = item.MetaIndexKeyword; 
       MetaIndexDesc = item.MetaIndexDesc; 
       MetaIndexTitle = item.MetaIndexTitle; 
       MetaGetPrefrenceKeyword = item.MetaGetPrefrenceKeyword; 
       MetaGetPrefrenceDesc = item.MetaGetPrefrenceDesc; 
       Logo = item.Logo; 
       Favicon = item.Favicon; 
       NoImage = item.NoImage; 
       SiteName = item.SiteName; 
       SiteTitle = item.SiteTitle; 
       SiteUrl = item.SiteUrl; 
       FbAndTwitterShareMessage = item.FbAndTwitterShareMessage; 
       CharacterSet = item.CharacterSet; 
       SiteMaintanance = item.SiteMaintanance; 
       PasswordChar = item.PasswordChar; 
       HtmlMetaKeyword = item.HtmlMetaKeyword; 
       HtmlMetaDescription = item.HtmlMetaDescription; 
       MetaDataGoogleSiteMap = item.MetaDataGoogleSiteMap; 
       WebMasterEmail = item.WebMasterEmail; 
       SupportEmail = item.SupportEmail; 
       NoReplyName = item.NoReplyName; 
       NoReplyEmail = item.NoReplyEmail; 
       DeleteExpireDeals = item.DeleteExpireDeals; 
       DealsPerPageBeforeLogin = item.DealsPerPageBeforeLogin; 
       DealsPerPageAfterLogin = item.DealsPerPageAfterLogin; 
       RecentViewDeals = item.RecentViewDeals; 
       BoughtDeals = item.BoughtDeals; 
       FbFanPage = item.FacebookFanPage; 
       FbApplicationId = item.FbApplicationId; 
       FbSecret = item.FbSecret; 
       FbApiSharingDeals = item.FbApiSharingDeals; 
       GoogleApiKey = item.GoogleApiKey; 
       TwitterScreenName = item.TwitterScreenName; 
       TwitterConsumerKey = item.TwitterConsumerKey; 
       TwitterConsumerSecret = item.TwitterConsumerSecret; 
       SharingAppId = item.SharingAppId; 
       SharingAppSecret = item.SharingAppSecret; 
       SharingCanvasURL = item.SharingCanvasURL; 
       InviteMessage = item.InviteMessage; 
       SharingMsgLink = item.SharingMsgLink; 
       ShareMsgPicture = item.ShareMsgPicture; 
       ShareMsgName = item.ShareMsgName; 
       ShareMsgCaption = item.ShareMsgCaption; 
       ShareMsgDesc = item.ShareMsgDesc; 
      } 

     } 

     public static string MetaIndexKeyword { get; set; } 
     public static string MetaIndexDesc { get; set; } 
     public static string MetaIndexTitle { get; set; } 
     public static string MetaGetPrefrenceKeyword { get; set; } 
     public static string MetaGetPrefrenceDesc { get; set; } 
     public static string Logo { get; set; } 
     public static string Favicon { get; set; } 
     public static string NoImage { get; set; } 
     public static string SiteName { get; set; } 
     public static string SiteTitle { get; set; } 
     public static string SiteUrl { get; set; } 
     public static string FbAndTwitterShareMessage { get; set; } 
     public static string CharacterSet { get; set; } 
     public static string SiteMaintanance { get; set; } 
     public static string PasswordChar { get; set; } 
     public static string HtmlMetaKeyword { get; set; } 
     public static string HtmlMetaDescription { get; set; } 
     public static string MetaDataGoogleSiteMap { get; set; } 
     public static string WebMasterEmail { get; set; } 
     public static string SupportEmail { get; set; } 
     public static string NoReplyName { get; set; } 
     public static string NoReplyEmail { get; set; } 
     public static bool? DeleteExpireDeals { get; set; } 
     public static int? DealsPerPageBeforeLogin { get; set; } 
     public static int? DealsPerPageAfterLogin { get; set; } 
     public static int? RecentViewDeals { get; set; } 
     public static int? BoughtDeals { get; set; } 
     public static string FbFanPage { get; set; } 
     public static string FbApplicationId { get; set; } 
     public static string FbSecret { get; set; } 
     public static string FbApiSharingDeals { get; set; } 
     public static string GoogleApiKey { get; set; } 
     public static string TwitterScreenName { get; set; } 
     public static string TwitterConsumerKey { get; set; } 
     public static string TwitterConsumerSecret { get; set; } 

     public static string SharingAppId { get; set; } 
     public static string SharingAppSecret { get; set; } 
     public static string SharingCanvasURL { get; set; } 
     public static string InviteMessage { get; set; } 
     public static string SharingMsgLink { get; set; } 
     public static string ShareMsgPicture { get; set; } 
     public static string ShareMsgName { get; set; } 
     public static string ShareMsgCaption { get; set; } 
     public static string ShareMsgDesc { get; set; } 

    } 
} 

回答

5

使全局託管的上下文不會導致連接池問題。但是,上下文包含訪問所有數據的DBSets,因此上下文將會增長,直到內存不足(假設您的數據庫大於可用內存)。

但是上下文創建起來很便宜,您爲什麼要在全球範圍內管理它?

- 應對新的信息

我不認爲你是顯示的代碼片段是問題背後的根本。相反,通過查看代碼跟蹤,問題似乎發生在SiteDetails的構造函數中。這是構造函數加載大量的數據?如果操作系統,你可能只是壓倒數據庫,因爲太多的線程試圖加載太多的數據。

+0

我已添加以下說明。 –

+0

我已經添加了SiteDetails的構造函數,請大家好好看看這個。 –

+0

您可能會在該構造函數中加載大量數據。如果直接對數據庫運行查詢,需要多長時間才能完成?它是否加載了很多行?而且,也許最重要的是,在任何給定的時間點創建多少個SiteDetails對象。我想知道是否有足夠多的SiteDetails對象被創建,這些對象正在使用所有可用的連接,從而導致您的問題。 –

6

它不應該導致連接池問題,因爲數據庫連接僅打開,使用,當你調用SubmitChanges關閉。

由於DBContext不是線程安全的,因此如果您的存儲庫實例被多個線程使用,它將導致問題。

另一個問題將是由EF在DBContext實例內完成的數據緩存 - 如果您不處理DBContext實例,則此緩存數據將會累積並在一段時間後會變得相當大,直到它導致內存壓力。

由於上述兩種原因(並且重新創建上下文沒有太多開銷),將DBContext用法保留在using塊中總體上是更好的做法。