Based on the link here which talks about connection pooling I see we are creating a new SqlConnection object which takes a parameter 'connectionString'
How to use connection pool without passing the connection string? We retrieve the connection string securely but across the application we are passing around the string which makes the connection string available in memory dumps.
I am looking for a similar approach in C# way it is done in Java. We create the datasource object and ask for a connection but we do not pass around the connection string.
How to achieve the same in C# ADO.NET connection pools?
TIA
Edit: What I meant by passing around the string (this code is present in every method in database access layer):
using (SqlConnection connection = new SqlConnection($conn_string))
{
connection.Open();
// execute queries
}
If you are concerned about database credentials in memory dumps, don't use them.
Instead, you can
Use SQL Server integrated authentication
If for some reason you can't work with a domain service account, use a DSN
If you still want a factory you can use something like the EF's SqlConnectionFactory or of course write your own.
Related
I want to use a connection pooling in my C# project. I understand that one I get the connection to the SQL server, while I'm using the same connection string, the cash pooling will work.
However I have doubts about: how is the best practice to pass the connection string through my different classes? Should I pass the connection string as a parameter to the methods that use it to connect? (for instance each time that I need to do a query)
ADO.NET has built-in connection pooling, and you can't really build a better one.
When you create a connection using a connection string, the Framework checks the connection pool to see if a connection with that connection string is available. If one is, it pulls it from the pool and returns it to you; otherwise, it creates a new one and returns that to you.
Similarly, when you close (dispose of) a connection, it is not immediately destroyed.
When you close a connection with a specific connection string, it is not immediately destroyed. Instead, it is released back into the connection pool.
Automatic connection pooling can be disabled, so that you could roll your own solution, but it's not advisable.
EDIT:
As pointed out, I didn't answer the question in my original answer.
In general, you don't pass connection strings around. Instead, they are stored in a configuration file (either web.config or app.config), in the connectionStrings section. When you need a connection string, you retrieve it within the method that requires it using ConfigurationManager.ConnectionStrings.
I am using the following code in conjunction with dapper ORM to connect to a database :
using (IDbConnection db = new SqlConnection(ConnectionString()))
{
return db.Query<object>(Sql).ToList();
}
The connection string contains database name and login information. I am wondering if while establishing connection to the database server, if any of that information could be visible to someone else.
If you mean in transit: you can force SQL Server to use encrypted connections - https://technet.microsoft.com/en-us/library/ms189067(v=sql.105).aspx
If you mean in-process - the key parts are removed by default so they won't be trivially available to other code with the SqlConnection instance; this is related to the "Persist Security Info" parameter on SqlConnection's connection-string, which defaults to false. Basically, the .ConnectionString property does not expose the credentials once provided. Note that the string will still have existed in memory at some point, so someone with raw access to the process and memory analysis tools may still be able to obtain it; see https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring(v=vs.110).aspx
However, you could also just use Windows authentication via SSPI - this then just uses the app-domain's executing user identity info to connect. Same link as above, but see the "Integrated Security" connection-string parameter.
On the Local Computer: Yes, it would be possible to get access to the information
Over the Network DB Connections: Depends on DB, SQL Server supports SSL, but if you don't use that then you'd be exposing information in your traffic
This would entirely depend on where the connection is being established from and where the connection is being established to.
If either end is in the hands of someone for example, in a distributed client, then they will be able to get hold of the connection details. Typically however, a connection is established "behind the scenes", something like from a web server to a database. Because a connection established like this is all "server side", the connection string is never visible to the "client" of the application and is therefore generally perceived to be safe - of course it is still at the mercy of the infrastructure! :)
It's worth nothing that if this is something like a thick client running on a domain then using something like Windows credentials is an option and would be as secure as the account.
I'm just wondering has anybody tried this. It seems so crazy that I need to open a mysql Connection for every call to the database. Sometimes a page requires 3 of 4 calls to the database and it takes extra time to open the connection.
if I create a new Session class and {get;set}; my connection in that class. Is there any harm in this? Theoretically I would this that performance would be increased. Has anybody tried it? And is there any big setbacks?
The MySql Connector/Net supports connection pooling and this is enabled by default.
Typically, you want to close your connection as soon as possible to avoid using up the pool, so storing the connected MySqlConnection in the session would be a bad idea.
You can manage the session without closing on every call by setting it up in the global.asax Session_start Method then closing it in the Sessions_Stop method.
You cannot store a MySqlConnection in a session. It simply isn't possible. The class isn't even serializable so if you used out-of-proc sessions your application would probably explode with an exception.
You can store a reference to a connection in the application domain by using a global class or Global.asax but with pooling this is needless anyhow, you should allow pooling to manage your connections.
I am tracing a bug in a library I did not write myself. When using this library with ASP.NET, I get db connection errors because the SQLConnection seems to get closed when a second Connection is being opened with the same connection string.
Is this documented behaviour? Can opening a new SQLConnection with the same connection string close another SQLConnection object?
From debugging that seems to be the most likely cause for my problems, but I could not find anything on the web to support my theory.
No, what will happen is that when you call the SqlConnection.Open() method, even with the same connection string parameters, it will do one of two things: either reuse an unused connection from the pool, or create a new connection. Either way, you will result in non-conflicting SPIDs for SQL Server.
Is this documented behaviour?
No.
Can opening a new SQLConnection with the same connection string close another SQLConnection object?
No.
Note that unless you've modified the settings, SQL Server permits 32,767 simultaneous connections. But even then, that would not explain the behavior that you are seeing.
In short, opening a new connection with the same connection string will not close your existing connection. However... reusing the already existing object by creating a new reference to a new connection will destroy the connection.
We have some client code which is using the SqlConnection class in .NET to talk to a SQLServer database. It is intermittently failing with this error:
"ExecuteReader requires an open and available Connection. The connection's current state is Closed"
The "temporary" solution is to reboot the process, after which everything works - however, that's obviously unsatisfactory.
The code is keeping a cache of SqlConnection instances, one for each database.
We'd like to re-write the code, but before I do, I need to know a few things:
My first question is: Is it inefficient to repeatedly connect and disconnect SqlConnection objects, or does the underlying library perform connection pooling on our behalf?
// Is this bad/inefficient?
for(many-times)
{
using(SQLConnection conn = new SQLConnection(connectionString))
{
// do stuff with conn
}
}
Because our code does not do the above, what seems the likely cause of the problem is that something happens to the underlying SQLServer database during the "lifetime" of the connection that causes the connection to be closed...
If it turns out that it is worthwile to "cache" SqlConnection objects, what is the recommended way to handle all errors that could be resolved simply by "reconnecting" to the database. I'm talking about scenarios such as:
The database is taken offline and brought back online, but the client process had no open transactions while this was happening
The database was "disconnected", then "reconnected"
I notice that there is a "State" property on SqlConnection... is there an appropriate way to query that?
Finally, I have a test SQLServer instance set up with full access rights: how can I go about reproducing the exact error "ExecuteReader requires an open and available Connection. The connection's current state is Closed"
No, it's not inefficient to create lots of SqlConnection objects and close each of them when you're done. That's exactly the right thing to do. Let the .NET framework connection pooling do its job - don't try to do it yourself. You don't need to do anything specific to enable connection pooling (although you can disable it by setting Pooling=false in your connection string).
There are many things that could go wrong if you try to cache the connection yourself. Just say no :)
You should enable connection pooling on your connection string. In that case the runtime will add back your connections to the 'pool' when you close them, instead of really disconencting. When a 'new' connection is taken out of the pool it will be reset (ie. sp_reset_connection is called ) then presented to your application as a brand new, fresh connection. The pool is handling transparently such cases as if the connection is closed while idling in the pool.
The cost of creating a new connection 'from scratch' is significant because the authentication requires several roundtrips between client and server (depending on the authentication method and on SSL settings it can be 1 roundtrip in best case vs. about 10 in worse).
And to answer your question, connection raise the OnStateChange event when their state changes, but you shouldn't care about this if you use the pooling.
In my recent experience if you use this code:
using(SQLConnection conn = new SQLConnection(connectionString))
{
// do stuff with conn
}
have an error, and do not explicitly close the connection, it will not be closed or checked back into the pool. So use a catch or finally block to close the connection