问题描述
我在我的Web API服务中使用Entity Framework 6.1.3,代码优先。
I am using Entity Framework 6.1.3 in my Web API service with code first approach.
我有API的自定义消息处理程序。从每个请求的消息处理程序,我通过调用MyContext.Open()打开数据库连接,并通过调用MyContext.Close()关闭数据库连接。
I had custom Message handler for API. From message handler for every request i opens db connection by invoking MyContext.Open() and closes the db connection by invoking MyContext.Close().
连续运行2天后(即此Web)客户端每3秒钟就会接受一次API服务。)我得到了带有连接池错误的执行时间。
After 2 days running continously(i.e this Web API service is accesed by client for every 3 seconds.) i get time out execption with coonection pool error.
当我检查日志时,显示数据库连接已关闭。我不知道为什么我会收到这个错误。
When I check log it show db connection is closed. I dont know why i am getting this error.
----------------------------- -------------------------------------------------- -----------------------------------------
------------------------------------------------------------------------------------------------------------------------
以下是错误日志:
Below is the error log:
System.Data.Entity.Core.EntityException:底层提供程序在Open上失败。 ---> System.InvalidOperationException:超时已过期。 从池中获取连接之前经过的超时时间。 这可能是因为
所有池化连接都在使用中并且达到了最大池大小。
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> 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.
在System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection,TaskCompletionSource`1 retry,DbConnectionOptions userOptions,DbConnectionInternal oldConnection,DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
在System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection,DbConnectionFactory connectionFactory,TaskCompletionSource`1 retry,DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
在System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1重试)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
在System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1重试)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
在System.Data.SqlClient.SqlConnection.Open()
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch [TTarget,TInterceptionContext](TTarget target,Action`2操作,TInterceptionContext interceptionContext,Action`3执行,Action`3执行)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
在System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open(DbConnection connection,DbInterceptionContext interceptionContext)
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open(DbConnection connection, DbInterceptionContext interceptionContext)
在System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy。<> c__DisplayClass1。<执行> b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
在System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute [TResult](Func`1操作)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
在System.Data.Entity.Core.EntityClient.EntityConnection.Open()
at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
---内部异常堆栈跟踪结束---
--- End of inner exception stack trace ---
在System.Data.Entity.Core.EntityClient.EntityConnection.Open()
at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
----------------------- -------------------------------------------------- -------------------------------------------------- -----------
--------------------------------------------------------------------------------------------------------------------------------------
Coonection String:
Coonection String:
< connectionStrings>
&NBSP; &NBSP; < add name =" abc" connectionString =" data source = Server1 \abc; initial catalog = TestDB; persist security info = True; user id = username; password = XXXX; multipleactiveresultsets = True; application name = EntityFramework"的providerName = QUOT; System.Data.SqlClient的"
/>
< / connectionStrings>
<connectionStrings>
<add name="abc" connectionString="data source=Server1\abc;initial catalog=TestDB;persist security info=True;user id=username;password=XXXX;multipleactiveresultsets=True;application name=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
---------------------------------- -------------------------------------------------- ----------------------------------
----------------------------------------------------------------------------------------------------------------------
下面是消息处理程序班级代码:
Below is the message handler class code:
public class MessageHandler:DelegatingHandler,IExceptionHandler
&NBSP; {
&NBSP; &NBSP; &NBSP; public MessageHandler()
&NBSP; &NBSP; &NBSP; {
$
&NBSP; &NBSP; &NBSP; }
&NBSP; &NBSP; &NBSP; protected override async Task< HttpResponseMessage> SendAsync(HttpRequestMessage请求,CancellationToken cancellationToken)
&NBSP; &NBSP; &NBSP; {&NBSP; &NBSP; &NBSP;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP;试试
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; MyContext.Open();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; catch(例外情况)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; MyContext.Close();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; } &NBSP; &NBSP; &NBSP;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP;试试
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; response = await base.SendAsync(request,cancellationToken);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; catch(例外情况)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; MyContext.Close(); &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; } &NBSP; &NBSP; &NBSP; &NBSP;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP;终于
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; { &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; MyContext.Close(); &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }
}
}
public class MessageHandler : DelegatingHandler, IExceptionHandler
{
public MessageHandler()
{
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{
MyContext.Open();
}
catch (Exception ex)
{
MyContext.Close();
}
try
{
response = await base.SendAsync(request, cancellationToken);
}
catch (Exception ex)
{
MyContext.Close();
}
finally
{
MyContext.Close();
}
}
}
---- -------------------------------------------------- -------------------------------------------------- ------------------
--------------------------------------------------------------------------------------------------------------------------
以下是MyContext类 代码 &NBSP; &NBSP; &NBSP;
Below is MyContext class code
公共课MyContext
&NBSP; {
private static Context instance = null;
private Context(){}
public MyDBContext MyDBContext {get; set; }¥b $ b &NBSP; public static MyContext Instance
&NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP;得到
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(instance == null)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
instance = new MyContext();
instance.MyDBContext = new MyDBContext();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; 返回实例;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;返回实例;
}
}
public static Open()
{
if(instance.MyDBContext!= null)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
$
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(instance.MyDBContext.ObjectContext.Connection.State!= ConnectionState.Open)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; instance.MyDBContext.ObjectContext.Connection.Open();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }
$
&NBSP; &NBSP; &NBSP; &NBSP; }
}
public staic Close()
{
if(instance.MyDBContext!= null)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(instance.MyDBContext.ObjectContext.Connection.State!= ConnectionState.Closed)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; instance.MyDBContext.ObjectContext.Connection.Close();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; Log.Info(" DB Connection:" + ConnectionState.Closed.ToString());
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; instance.MyDBContext.Dispose();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }
}
}
public class MyContext
{
private static Context instance = null;
private Context(){}
public MyDBContext MyDBContext {get;set;}
public static MyContext Instance
{
get
{
if (instance == null)
{
instance = new MyContext();
instance.MyDBContext = new MyDBContext();
return instance;
}
return instance;
}
}
public static Open()
{
if (instance.MyDBContext != null)
{
if (instance.MyDBContext.ObjectContext.Connection.State != ConnectionState.Open)
{
instance.MyDBContext.ObjectContext.Connection.Open();
}
}
}
public staic Close()
{
if (instance.MyDBContext != null)
{
if (instance.MyDBContext.ObjectContext.Connection.State != ConnectionState.Closed)
{
instance.MyDBContext.ObjectContext.Connection.Close();
Log.Info("DB Connection :" + ConnectionState.Closed.ToString());
}
instance.MyDBContext.Dispose();
}
}
}
公共类MyDBContext:DBContext
public class MyDBContext:DBContext
{
public ObjectContext ObjectContext
&NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; get {return(this as IObjectContextAdapter).ObjectContext; }¥b $ b &NBSP; &NBSP; &NBSP; }
public ObjectContext ObjectContext
{
get { return (this as IObjectContextAdapter).ObjectContext; }
}
}
-------------------------- ------------------
--------------------------------------------
Will" instance.MyDBContext.ObjectContext.Connection.Close(); "代码行真的关闭了连接?我怀疑这里有些问题。
Will "instance.MyDBContext.ObjectContext.Connection.Close(); " line of code really closeses the connection? I suspect some problem here.
请回复查询。我急需解决这个问题。
Please reply the query. I am in urgent to fix this issue.
Ravishankar Boyina
Ravishankar Boyina
推荐答案
>>将< instance.MyDBContext.ObjectContext.Connection.Close(); "代码行真的关闭了连接?我怀疑这里有一些问题。
>> Will "instance.MyDBContext.ObjectContext.Connection.Close(); " line of code really closeses the connection? I suspect some problem here.
从以下代码中可以看出,如果它没有抛出任何异常,你就没有关闭它。请在使用后关闭它。
From the following code, it seems that you have not close it if it doesn't throw any exception. please close it after you use it.
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{
MyContext.Open();
//你处理逻辑
MyContext.Close();
}
catch(Exception ex)
{
MyContext.Close() ;
}
MyContext.Close(); } catch (Exception ex) { MyContext.Close(); }
此外,我建议您可以使用工作单元模式而不是单例模式。以及以下链接的一些原因。
In addition, I would suggest that you could use unit of work pattern instead of singleton pattern. and the following link some reasons.
http://www.britishdeveloper.co.uk/2011/03/dont-use-singleton-datacontexts-entity.html
有关单位的更多信息工作,请参考:
For more information about unit of work, please refer to:
注意:此响应包含对第三方万维网站点的引用。 Microsoft提供此信息是为了方便您。
Note: This response contains a reference to a third party World Wide Web site. Microsoft is providing this information as a convenience to you.
Microsoft不控制这些网站并且未测试任何网站在这些网站上找到的软件或信息;因此,Microsoft不能就任何
软件或信息的质量,安全性或适用性做出任何陈述。
Microsoft does not control these sites and has not tested any software or information found on these sites;Therefore, Microsoft cannot make any representations regarding the quality, safety, or suitability of any software or information
found there.
使用互联网上的任何软件都存在固有的危险,微软提醒您在检索之前确保完全理解风险来自互联网的软件。
There are inherent dangers in the use of any software found on the Internet, and Microsoft cautions you to make sure that you completely understand the risk before retrieving any software from the Internet.
祝你好运,
Cole Wu
这篇关于(DbContext as IObjectContextAdapter).ObjectContext.Conncection.Close()在EF6中不起作用。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!