Good technique for connections with PostgreSQL - c#

I am using Npgsql to access PostgreSQL via .NET. I am concerned about the right way to perform connections to the database, since in my opinion this is an expensive operation to open a connection and then close it every single time I want to perform some transaction.
So here is the general idea:
public class PostgreSQL
{
private NpgsqlConnection conn; // <- one connection for this object, open all the time
public PostgreSQL(string connString)
{
conn = new NpgsqlConnection(connString);
conn.Open();
}
// ...here making some queries...
public void Close() => conn.Close(); // <- use this in the very end of the program
}
As you can see above, I have one connection for an instance of PostgreSQL class.
My question:
Is this approach right? Or should I open and close connection every single time I want to make a transaction - open as late as possible and close as soon as possible?
If I should open and close connections every single time - should I write a queue that would limit the amount of concurrent connections? Or PostgreSQL will handle it itself - and, theoretically, I can open 200 connections and it will be alright.
Please share your experience with me ^^
EDIT:
I will run 100-200 queries a second.

PostgreSQL supports connections pooling (pool size is customizable) so the common pattern:
using (NpgsqlConnection conn = new NpgsqlConnection(...))
{
...
}
should be the better choice.

In my opinion you should open a connection at the moment you need it, and close it right after it. This will prevent a lot of connections on the server to be kept alive.
In my experience, opening a connection doesn't take that much time (a few milliseconds, usually a fraction of your execution time), so you don't have to worry too much.

Related

How to manage SqlConnection in C# for high frequency transaction?

I have an application that connect to a SQL Server database with high frequency. Inside this service, there are many scheduled tasks that run every second, and each time I'm executing some query.
I don't understand which solution is better in this condition.
Opening a single SqlConnection and keeping it open while application is running and execute all query with that connection
Each time I want to execute query, opening a new connection and after query execution, close the connection (does this solution suitable for so many scheduled task that runs every 1 second?)
I tried second solution, but is there any better choice?
How do ORMs like EF manage connections?
As you see i have many service. I cant change interval and the interval is important for me. but the code makes so many calls and im following a better way manage connection over database. Also I'm making connection with Using Statement.
Is there any better solution?
you should use SQL Connection Pool feature for that.
It automatically manages in the background if a connection needs to be open or can be reused.
Documentation: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling?source=recommendations
Example copied from that page
using (SqlConnection connection = new SqlConnection(
"Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// Pool A is created.
}
using (SqlConnection connection = new SqlConnection(
"Integrated Security=SSPI;Initial Catalog=pubs"))
{
connection.Open();
// Pool B is created because the connection strings differ.
}
using (SqlConnection connection = new SqlConnection(
"Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// The connection string matches pool A.
}
By using the "using" statement, application checks if a connection in this pool can be reused before opening a new connection. So the overhead of opening and closing the connections disappears.
But after your last edit you seem to have other problems in your current architecture. Like the other poster recommends you can try to use the "with (nolock)" parameter in your sql statements. It creates dirty reads, but maybe that's ok for your application.
Alternatively if all your services use the same select statement maybe a stored procedure or a caching mechanism could help.
I assume that you are already opening/closing your SQL connections in either a "using" statement or explicitly in your code ( try/catch/finally ). If so you are already making use of connection pooling as it is enabled in ADO.Net by default ("By default, connection pooling is enabled in ADO.NET").
Therefore I don't think that your problem is so much a connection/resource problem as it is a database concurrency issue. I assume it to be either 1 of 2 issues :
Your code is making so many calls to the SQL server that it is exhausting all the available connections and nobody else can get one
Your code is locking tables in SQL that is causing other code/applications to timeout
If it is case 1, try and redesign your code to be "less chatty" to the database. Instead of making several inserts/updates per second, perhaps buffer the changes and make a single insert/update every 3-5 seconds in batch mode ( obvs if possible ). Or maybe your SQL statements are taking longer than 1 second to execute and you are calling them every second causing in a backlog scenario?
If it is case 2, try and redesign the SQL tables in such a way that the "reading" applications are not influenced by the "writing" application. Normally this involves a service that periodically writes aggregated data to a read-only table for viewing or at very least adding a "WITH(NOLOCK)" hint to the select clauses to allow dirty reads ( i.e. it wont lock the table to read, but may result in slightly out of date dataset i.e. eventual consistency )
Good luck

Is overutilisation of Sql Connections in C# a problem?

Throughout the program which I am currently working on, I realized that whenever I need to access to SQL Server, I just type a queryString and execute my query using SqlCommand and SqlConnection in C#. At a certain point during the program, I even opened a connection and ran a query in a "for loop".
Is it unhealthy for the program to constantly open-close connections?
***I am not very familiar with the terminology, therefore you might be having some problems understanding what I am talking about:
Is doing this very frequently may cause any problem?:
string queryString = "Some SQL Query";
public void(){
SqlConnection con = new Connection(conString);
SqlCommand cmd = new SqlCommand(queryString,con);
cmd.Parameters.AddWithValue("#SomeParam",someValue);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
I use this template almost every class I create,(usually to get,update,insert data from/into a datatable).
Well, is it harmful?
The short answer is yes - it is inefficient to constantly open and close connections. Opening an actual connection is a very expensive process and managing a connection for the lifetime of its need (which usually is the lifetime of the application or process using it) is fraught with errors.
That is why connection pooling was introduced a long time ago. There is a layer beneath your application that will manage the physical opening/closing of connections in a more efficient way. This also helps prevent the chances that an open connection is lost and continues to stay open (which causes lots of problems). By default pooling is enabled so you don't need to do anything to use it.
With pooling - you write code to open a connection and use it for the duration of a particular section of code and then close it. If the connection pool has an open but unused connection, it will reuse it rather than open a new one. When you close the connection, that simply returns the connection to the pool and makes it available to the next open attempt. You should also get familiar with the c# using statement.

"open/close" SqlConnection or keep open?

I have my business-logic implemented in simple static classes with static methods. Each of these methods opens/closes SQL connection when called:
public static void DoSomething()
{
using (SqlConnection connection = new SqlConnection("..."))
{
connection.Open();
// ...
connection.Close();
}
}
But I think passing the connection object around and avoiding opening and closing a connection saves performance. I made some tests long time ago with OleDbConnection class (not sure about SqlConnection), and it definitely helped to work like this (as far as I remember):
//pass around the connection object into the method
public static void DoSomething(SqlConnection connection)
{
bool openConn = (connection.State == ConnectionState.Open);
if (!openConn)
{
connection.Open();
}
// ....
if (openConn)
{
connection.Close();
}
}
So the question is - should I choose the method (a) or method (b) ? I read in another stackoverflow question that connection pooling saved performance for me, I don't have to bother at all...
PS. It's an ASP.NET app - connections exist only during a web-request. Not a win-app or service.
Stick to option a.
The connection pooling is your friend.
Use Method (a), every time. When you start scaling your application, the logic that deals with the state will become a real pain if you do not.
Connection pooling does what it says on the tin. Just think of what happens when the application scales, and how hard would it be to manually manage the connection open/close state. The connection pool does a fine job of automatically handling this. If you're worried about performance think about some sort of memory cache mechanism so that nothing gets blocked.
Always close connections as soon as you are done with them, so they underlying database connection can go back into the pool and be available for other callers. Connection pooling is pretty well optimised, so there's no noticeable penalty for doing so. The advice is basically the same as for transactions - keep them short and close when you're done.
It gets more complicated if you're running into MSDTC issues by using a single transaction around code that uses multiple connections, in which case you actually do have to share the connection object and only close it once the transaction is done with.
However you're doing things by hand here, so you might want to investigate tools that manage connections for you, like DataSets, Linq to SQL, Entity Framework or NHibernate.
Disclaimer: I know this is old, but I found an easy way to demonstrate this fact, so I'm putting in my two cents worth.
If you're having trouble believing that the pooling is really going to be faster, then give this a try:
Add the following somewhere:
using System.Diagnostics;
public static class TestExtensions
{
public static void TimedOpen(this SqlConnection conn)
{
Stopwatch sw = Stopwatch.StartNew();
conn.Open();
Console.WriteLine(sw.Elapsed);
}
}
Now replace all calls to Open() with TimedOpen() and run your program. Now, for each distinct connection string you have, the console (output) window will have a single long running open, and a bunch of very fast opens.
If you want to label them you can add new StackTrace(true).GetFrame(1) + to the call to WriteLine.
There are distinctions between physical and logical connections. DbConnection is a kind of logical connection and it uses underlying physical connection to Oracle. Closing/opening DbConnection doesn't affect your performance, but makes your code clean and stable - connection leaks are impossible in this case.
Also you should remember about cases when there are limitations for parallel connections on db server - taking that into account it is necessary to make your connections very short.
Connection pool frees you from connection state checking - just open, use and immediately close them.
Normally you should keep one connect for each transaction(no parallel computes)
e.g when user execute charge action, your application need find user's balance first and update it, they should use same connection.
Even if ado.net has its connection pool, dispatching connection cost is very low, but reuse connection is more better choice.
Why not keep only one connection in application
Because the connection is blocking when you execute some query or command,
so that means your application is only doing one db operation at sametime,
how poor performance it is.
One more issue is that your application will always have a connection even though your user is just open it but no operations.If there are many user open your application, db server will cost all of its connection source in soon while your users have not did anything.

I am continuously querying database; should there be any problem?

In my application, I am querying database with same sql every one second. I need to know what measure should I take. Will it ever cause any problem like " The
timeout period elapsed prior to obtaining a connection from the pool." or any other like that?
Currently, i am creating a new connection every second and the disposing it after it is used. Should I reuse connection in this case.
Whats the best approach?
IMHO best practice is to pump-and-dump connections as quickly as possible - use them to get access to what you need and close them right away. Your enemy performance-wise isn't the overhead it takes to create a connection (although there is some involved there) - it's locking a table in your database.
If you're looking to optimize your application, you should try to implement some sort of caching mechanism that saves you from having to make a round-trip to the database for each lookup. That would be to your benefit performance-wise.
Another thing you can do is use read-only connections where you can - they require less overhead than traditional ones and will improve your performance also.
You should definitely open and close the connection each time. Indeed, if your using block has much code after the last use of the connection, call Close() to get it back in the pool as soon as possible. That way the chance of another use not needing to open a completely new connection is reduced (see What does "opening a connection" actually mean? for a bit more on when a real connection is opened and when one is taken from the pool).
Is this "once a second" an average across different threads, or all on the one thread? If it's all on the one thread it doesn't matter, indeed it might even be slightly faster to keep the connection object open, because either way there won't be contention for it.
I would certainly consider caching results, though this has downsides in memory use, along with potentially complicated issues about when the cached results need to be refreshed - really this could be anywhere from trivial to impossible depending on just what you are doing.
It's also clearly a query to go that extra mile when optimising.
Why do you need to do this?
You could try caching the data to reduce the load on your database. Do you need data that is 1 second old, or is 5 seconds ok.
Closing the connection after each time you use it is OK. It does not really get closed, it just goes back into the connection pool.
If the library you're using does indeed pool the connections for you then it doesn't make a difference. If not, then it would be better to use the same connection multiple times. Creating a connection is time consuming.
A few questions...
What data are you getting from the database?
Could that data be stored in application memory?
There is no problem in such approach if you dispose connections like this:
using (SqlConnection cnn = new SqlConnection(ConnectionString))
{
SqlCommand cmd = new SqlCommand(commandText, cnn)
{
CommandType = CommandType.Text
};
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
return ds;
}
The only problem may happen - is decreasing your db performance if your hardware isn't good enought.

How can I keep a Connection open when performing multiple queries?

I am using multiple queries to pull data from the same server in my application. The issue is that I have to open a new connection every time I have a new query.
Is it even possible to:
Open the connection
Run query
Pull results
Run another query
Pull another result
Run final query
Pull another result
Close connection.
Although you may not yet know it, you are doing it correctly.
Open the connection, do your query, close it. Preferably using a using block or try/finally.
This may sound like a lot of overhead, but the connection pool in the .NET Framework Data Provider for SQL Server will actually optimize this for you.
In fact closing the connection is recommended.
Here is a quote from the documentation:
It is recommended that you always
close the Connection when you are
finished using it in order for the
connection to be returned to the pool.
This can be done using either the
Close or Dispose methods of the
Connection object. Connections that
are not explicitly closed might not be
added or returned to the pool. For
example, a connection that has gone
out of scope but that has not been
explicitly closed will only be
returned to the connection pool if the
maximum pool size has been reached and
the connection is still valid.
Here is an example of some code that does this:
try {
conn.Open();
// Perform query here
} finally {
conn.Close();
}
For reference:
http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.71).aspx
If you are using ASP.NET with the same connection string you will be using a pooled connection that may never get physically closed, so you will pretty much always use an available open connection.
It's very possible. Assuming that you are talking about Connection and a DataReader. If you have to create a different connection every time, it sound like something is going wrong.
Without seeing any code, I am guessing that you are leaving the DataReader open. This is a BIG mistake. By default DataReaders completely consume the connection and leaving it unclosed can lead leaks. Close the DataReader, then execute another. I'd recommend wrapping the DataReader in a using block.
Rob
Short answer: Yes. This should be possible with most data providers.
Long answer: It depends on what you are using for your data access. However, you probably do not need to worry about it. Many data provider frameworks have connection pooling built in, so the subsequent connection creation/opening shouldn't "really" open a connection.
Sure, if you're using a SqlConnection object you can just do something like this:
connection.Open();
cmd.ExecuteReader(); // or any other form of getting the data
cmd2.ExecuteReader();
.
.
.
.
connection.Close();
I'd also like to add, if you're using a few SqlDataAdapters for your queries, although you normally don't need to open the connection by yourself, if you DO explicitly call connection.Open() it then won't close the connection for you automatically, allowing you to execute multiple queries with only one connection.
If you are using C# to open a connection. use using statement will help you clean up the resource/connection even if there is some excepion throwing out.
using (SqlConnection connection =
new SqlConnection(connectionString)
{
connection.Open();
//issue command
}
And read this:
http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.71).aspx, you can "Controlling Connection Pooling with Connection String Keywords", and the system will handle pooling for you.

Categories