Too many Oracle connections open - c#

I have a .NET Core web api on IIS running and I'm using oracle as database and I do connect to it like this.
using(OracleConnection con = new OracleConnection(connectionString))
{
OracleCommand cmd = new OracleCommand();
//some other code here
con.Open();
}
I'm not using EF or so. I (de)serialze the data from the reader directly into a json or xml string.
I have a small batch file to test the api. The batch sends a request using curl every second and when I run the batch file 5 times, to simulate a little bit of traffic, (I know there are some tools for that, but thats not the problem) the api has open 7 connections to the database. Why are 7 db connections open, how to handle it, so that a maximum of 2 or 3 simultaneously are open, even if a request has to wait?
I do not want to "just make it work", I want it to work the right way. Because of that, I want to now, is "connection pooling" the keyword here? Especially the max pool size, could I just set it to 3, or did I forget something to set up, or something?

Related

Should I keep the SqlConnection open?

In my Unity3D game the Player plays himself through short levels, which at the beginning take about 4 seconds. The goal is to get the best possible clear time in each level. I am currently saving these clear times locally, but I would like to upload them to an SQL Server, to be able to create a leaderboard for each level.
Since performing the SqlConnection.Open() command takes about 1-2 seconds, sometimes also 3, I was wondering whether I should keep a static connection always open, ready to execute any queries that I want to run.
Are there any unwanted and dangerous side-effects when doing it?
Edit: This is the code that I use for opening the SqlConnection.
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder()
{
DataSource = dataServer,
UserID = userId,
Password = password
};
SqlConnection connection = new SqlConnection(builder.ToString());
connection.Open();
First I'll answer this question:
Are there any unwanted and dangerous side-effects when doing it?
Assuming you keep this code in your Game (client) and the SQL Server is not client-side but in a server of yours located somewhere, a simple Client Reverse Engineer will be able to grab your credentials from your connection string and use them to gain Unauthorized access to your database. (NEVER trust the client)
With that being said, I would suggest you use a simple server-side technology (php,Socket App, Java servlet, etc..) along with the SQL that the client will send the information there and then to the database.
Example:
1) Client-> Posts Data -> PHP
2) PHP -> Connects -> SQL Database
3) PHP -> Inserts data -> SQL Database
Like this you can also retrieve the results of your ladder from the database by asking php (or whatever technology you are using) to send your data to the client.
Best wishes in your progress, and feel free to contact me for any additional information!

How to connect database with C# executable file?

I am writing code for a small company that is all about purchase and sell. I wrote C# code with using external database (SQL Server 2014), now it's time to make the exe file of that code.
I tried my best but it doesn't work.
How can I connect SQL Server 2014 database files with my application so that when someone installs it on his computer he also got SQL Server connected with that application?
Hi actually we deploy code as setup file (.msi), you can create setup project using Wix or install-shield ( maybe other too,but these two are most popular and widely used)
You can do database deployment in two ways
1.) you can provide SQL script for generating SQL server and give instruction for generating Database from Script. It is simple and easy to do.
2.) Other way is provide option to create database from setup. It need some work, but it is more good way.
Now come to your question, you can provide some UI in setup that take input from user and connect to appropriate DB. Or create a UI for Updating configurations, and save configuration (connection string ) in some file ( ex: .ini or .config file).
Below are the some URL for creating Setup and connecting to Db using Wix:
WIXDataBase
installing-databases-using-wix
Creating-an-installer-using-Wix
using-wix-to-install-sql-databases-and-execute-sql-scripts
WiX Samples
Ideally you'd have a SQL server set up somewhere. If not you'll have to install sql server. In your app it's just a matter of setting up the connection string and running sql commands against it.
string connectionString = "Data Source=server //rest of connection string"
Then in c# you can do
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand("SELECT TOP 100 * FROM SomeTable", con))
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("{0} {1} {2}",
reader.GetString(0), reader.GetString(1), reader.GetString(2));
}
}
}
GetString can be changed to GetInt or whatever the datatable will be. This should be enough information to get you started. If you know the structure of the database its simple to put the results into your classes for the application.

ADO.NET Max Pool Size Behavior

I'm using MSSQL 2008R2. I wrote a C# app and purposely did not close my SqlConnection. Debugging locally on VS 2010. Following is the code I used:
protected void Button1_Click(object sender, EventArgs e)
{
string connectionString = "server=s; database=db; User ID=sa; Password=p; Max Pool Size=1;Connect Timeout=3";
SqlConnection conn = new SqlConnection(connectionString);
string query = "SELECT * FROM dbo.Numbers";
SqlCommand comm = new SqlCommand(query, conn);
conn.Open();
SqlDataReader reader = comm.ExecuteReader();
//reader.Read() and display results to Textbox1.Text
}
Max Pool Size = 1; was expecting to error out on second click try on 2nd browser.
Why is it I can go to 3 different browsers (Mozilla, Chrome, IE) and call click method once each. That equates to 3 simultaneous connections right? The timeout error only occurs when I use a browser, but call method twice on that browser. Why is this?
Just because you left the connection object open doesn't imply three separate connections. The .NET framework actually leverages the connection pooling in SQL Server and manages it by connection string. Since the connection string was the same for all three requests - and the connection was available - there is no conflict.
Now, if you were to simulate a situation where you had a long running query start up on one of the requests and then try and hit it again - you would probably find that it would wait first - and you would get a timeout exception.
Here is a lengthy and dry document on connection pooling in the .NET framework on MSDN.
So there appears to be a discrepancy between debugging locally in VS 2010 and IIS 7.5. I had to deploy the sample web site to IIS for the max pool size to behave as expected. If I try to call click event a second time no matter which browser I try, it will throw timeout error, this is expected. Perform website/app pool restart/recycle as needed to retest.
For some reason debugging locally in VS 2010 bypasses max pool size restriction. Each browser may call click event which in my example opens 3 sqlconnection objects. The only time it throws the timeout error is if you stay in a browser and call click method twice. Strange behavior but something developers should be aware of.

SQL Server: Could not find prepared statement with handle x

Recently our QA team reported a very interesting bug in one of our applications. Our application is a C# .Net 3.5 SP1 based application interacting with a SQL Server 2005 Express Edition database.
By design the application is developed to detect database offline scenarios and if so to wait until the database is online (by retrying to connect in a timely manner) and once online, reconnect and resume functionality.
What our QA team did was, while the application is retrieving a bulk of data from the database, stop the database server, wait for a while and restart the database. Once the database restarts the application reconnects to the database without any issues but it started to continuously report the exception "Could not find prepared statement with handle x" (x is some number).
Our application is using prepared statements and it is already designed to call the Prepare() method again on all the SqlCommand objects when the application reconnects to the database. For example,
At application startup,
SqlCommand _commandA = connection.CreateCommand();
_commandA.CommandText = #"SELECT COMPANYNAME FROM TBCOMPANY WHERE ID = #ID";
_commandA.CommandType = CommandType.Text;
SqlParameter _paramA = _commandA.CreateParameter();
_paramA.ParameterName = "#ID";
_paramA.SqlDbType = SqlDbType.Int;
_paramA.Direction = ParameterDirection.Input;
_paramA.Size = 0;
_commandA.Parameters.Add(_paramA);
_commandA.Prepare();
After that we use ExceuteReader() on this _commandA with different #ID parameter values in each cycle of the application.
Once the application detects the database going offline and coming back online, upon reconnect to the database the application only executes,
_commandA.Prepare();
Two more strange things we noticed.
1. The above situation on happens with CommandType.Text type commands in the code. Our application also uses the same exact logic to invoke stored procedures but we never get this issue with stored procedures.
2. Up to now we were unable to reproduce this issue no matter how many different ways we try it in the Debug mode in Visual Studio.
Thanks in advance..
I think with almost 3 days of asking the question and close to 20 views of the question and 1 answer, I have to conclude that this is not a scenario that we can handle in the way we have tried with SQL server.
The best way to mitigate this issue in your application is to re-create the SqlCommand object instance again once the application detects that the database is online.
We did the change in our application and our QA team is happy about this modification since it provided the best (or maybe the only) fix for the issue they reported.
A final thanks to everyone who viewed and answered the question.
The server caches the query plan when you call 'command.Prepare'. The error indicates that it cannot find this cached query plan when you invoke 'Prepare' again. Try creating a new 'SqlCommand' instance and invoking the query on it. I've experienced this exception before and it fixes itself when the server refreshes the cache. I doubt there is anything that can be done programmatically on the client side, to fix this.
This is not necessarily related exactly to your problem but I'm posting this as I have spent a couple of days trying to fix the same error message in my application. We have a Java application using a C3P0 connection pool, JTDS driver, connecting to a SQL Server database.
We had disabled statement caching in our the C3P0 connection pool, but had not done this on the driver level. Adding maxStatements=0 to our connection URL stopped the driver caching statements, and fixed the error.

How do I reset an asp.net website within the site itself with a button?

I am working on an ASP.NET 2.0 website. The issue that I'm having is that it queries a database to get the info it displays on screen, but the database occasionally gets to where it has too many open connections. This causes the website to reject the attempt to log-in for anyone, after that database error.
This is caused because many users will log-in, do what they need to do, but then leave the website running while they do other things without logging out. It will time out on them, but the connection still seems to be open. We then have to contact the person in charge of the server it's running on and have him reset it for us.
I have looked and all connections made to the database seem to be closed after the request and query is made. So, what I want to do is to add a button that when clicked will reset the website, instead of having to call the guy in charge of the server every time. Then we can reset it whenever we need to. So, how do I reset an ASP.NET 2.0 website with a button on one of the pages inside the site?
Many thanks,
Mike
all connections made to the database seem to be closed after the request
The problem here is the word "seem". For example, this code "seems" like it will close the connection, but in some situations it won't:
var conn = new SqlConnection("MyConnection");
var cmd = new SqlCommand("query string here", conn);
cmd.ExecuteNonQuery();
conn.Close():
I can hear you saying, "Of course it closes the connection. Don't you see the 'conn.Close();' line?" The problem is that there are things that can happen that prevent the conn.Close() line from executing.
Instead, you need to do something like this:
using (var conn = new SqlConnection("MyConnection"))
using (var cmd = new SqlCommand("query string here", conn))
{
cmd.ExecuteNonQuery();
}
That code will always close the connection.
If you're really serious about "resetting" the application, you might try calling Environment.Exit(), but again: this is a bad idea.
I don't think adding a button to reset the website is the correct choice.
You should really look into why the connections aren't closing.
If you're using SqlConnections, then wrap them in a using statement, this will dispose of the connection after you're finished.
Here's an example:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Do work here; connection closed on following line.
}
To answer your actual question, the easiest way to reset a ASP.NET site is to just modify the web.config which will cause the site to reload.
So if I wanted to implement a button all I would do is set a value in the app settings that is meaningless (perhaps a date time of the last reset) and then use ConfigurationManager to save the changes.
MSDN reference: ConfigurationManager Class

Categories