http://jwcooney.com/2012/08/13/asp-net-error-adding-the-specified-count-to-the-semaphore-would-cause-it-to-exceed-its-maximum-count/

If you are working with ASP.NET in Visual Studio, then you may be mystified when you see an error code : Adding the specified count to the semaphore would cause it to exceed its maximum count.

This error had me wondering what exactly is going on…

Identifying the Problem

At first when I saw this error, I thought it might be due to the syntax of the query I was running. However after starting up Query Profiler I was able to run the query directly in SSMS without any issues. The problem clearly was somewhere in the application and not with the SQL query.

After investigating this, it appears that this error is related to ASP.NET’s ADO.NET connection pool manager. When you put together a connection string in your web.config file, you probably won’t be thinking about connection pooling, but by default this will be enabled. The connection pool manager will attempt to find a free connection, but if none are available it will throw the error we saw.

What is a Semaphore in SQL Server?

The first question I asked myself was what a semaphore is since I had not heard this term used before. Well, it seems that the definition of semaphore is just a locking mechanism used by SQL Server behind the scenes to prevent more than one task from accessing a data structure that is currently in use. In particular SQL Server protects user log caches using semaphores.

What is the cause of this problem?

So that was pretty interesting information. Basically with the error being returned, it appears that some sort of a lock was being retained and not released when my VB.NET application was communicating with SQL Server. It was definitely not a problem with long running queries or forgetting to clean up the connection object after execution was complete.

I’m still not able to pin down exactly what was causing this error to happen. People online speculate that similar problems appear to be caused by network issues. However, when I encountered the problem there were no noticeable network problems though, so I doubt that the network was causing the problem in my case.

Bottom line is that the semaphore locking issue appears to be  related to ASP.NET’s connection pooling. Resources were being locked in the pool and then were not being released, so I would see the semaphore error when my application was trying to access the application pool and no free resources were available.

Why Are Connection Pools Used By Default?

So since ADO.NET connection pools seem to be a possible point of failure, the question remains: why are connection pools enabled by default? The answer is performance.

There is a high performance hit involved with establishing a connection with a database, so ADO.NET tries to increase performance by not destroying connections after a call has happened to a database. Rather, ADO.NET puts the released connection into a pool which it holds for the next time that a request to the database is made. In general this ends up returning database results much faster than if connection pooling is disabled.

Of course we have also seen the down-side to connection pooling, which is the semaphore error where ADO.NET tries to access a connection in the pool, and finds that it can’t.

In the case of my application I decided that the possible performance improvement gained by using connection pooling was outweighed by the possibility of getting ugly connection errors such as the semaphore error, so next I will explain how to ‘fix’ the semaphore error by disabling ADO.NET connection pooling.

Fixing the Problem

The simplest way to fix the ADO.NET semaphore error is to disable connection pooling in the connection string of your web.config file.

Here is an example of what a default connection string might look like. Although it doesn’t specify a connection pooling option, this is enabled by default:

<add name="testConnection" connectionString="Data Source=MyDBServer;Initial Catalog=MyDatabase;Persist Security Info=True;User ID=testUserId;Password=TestPassword;"
providerName="System.Data.SqlClient" />

Now to disable pooling and get rid of the error message we were seeing, we simply append the directive Pooling=False to the end of our connection parameters as follows:

<add name="testConnection" connectionString="Data Source=MyDBServer;Initial Catalog=MyDatabase;Persist Security Info=True;User ID=testUserId;Password=TestPassword;Pooling=False;"
providerName="System.Data.SqlClient" />

Pretty simple, right?

Sometimes finding the reason for a problem is more difficult than fixing the problem. Now that I know what was causing the error I will find it easier to diagnose similar problems in future!

最新文章

  1. [转] 微软源代码管理工具TFS2013安装与使用详细图文教程(Vs2013)
  2. Linux系统重启python程序
  3. 设计模式学习之适配器模式(Adapter,结构型模式)(14)
  4. ORM框架
  5. 特征脸(Eigenface)理论基础-PCA(主成分分析法)
  6. Hadoop入门进阶课程11--Sqoop介绍、安装与操作
  7. [CareerCup] 9.6 Generate Parentheses 生成括号
  8. PHP 页面自动刷新可借助JS来实现,简单示例如下:
  9. setTimeout setInterval 区别 javascript线程解释
  10. window store app 附件读取
  11. 《Linux Device Drivers》 第十七章 网络驱动程序——note
  12. python 信用卡系统+购物商城见解
  13. Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(2)
  14. Inspinia_admin-V2.3原版(英文)
  15. [Java笔记]继承
  16. Apache POI导出excel表格
  17. 关于Spring MVC跨域
  18. document.createDocumentFragment 以及创建节点速度比较
  19. 使用C#创建WCF服务控制台应用程序
  20. 使用jstl+el表达式遇到的几个问题

热门文章

  1. kettle开源项目部署文档
  2. CentOS-7.x Yum Repo Mirror
  3. 冲刺Two之站立会议2
  4. centos 64位 下hadoop-2.7.2 下编译
  5. What is the difference between WinRT, UWP and WPF?
  6. C#简述(三)
  7. 11th 本周工作量及进度统计
  8. php环境搭建及入门
  9. Postgresql 简单安装过程. Study From https://www.cnblogs.com/stulzq/p/7766409.html
  10. FuelPHP 系列(一) ------ Oil 命令