I'm using ODP on my Oracle DB application.I registered to OracleConnection.StateChange event for watching the state of the connection. When i disconnect the db connection the event fires but for example if the internet connection is lost there is no action.
How can i handle these kind of(internet conenction lost etc.) situations via the StateChange event?
Or do i have to create a thread for checking the connnection state regularly?
If yes how can i check the connection because i checked the state and it seems to be open even i unplug the internet cable.
Regards.
The common way is to issue an unexpensive sql statement just before the connection is used for something. On oracle it is something like 'select 1 from dual', on ms-sql 'select 1'. This sql forces a roundtrip to the server and lost connection to the server is reported.
JBoss is using something called check-valid-connection-sql. Others have other names.
Related
How can I check the database connection using Entity Framework 6?
Here's my code:
using (var context = new DatabaseDataModel(connectionString))
{
if (context.Database.Connection.State != System.Data.ConnectionState.Open)
return;
if (!context.Database.Exists())
return;
context.Items.Add(item);
}
How can I check if the connection is established before adding my items to the database? I can't open the connection because it will take plenty of time in case of corrupt connection string. That means my state check above is meaningless. The same concerns for the context.Database.Exist(), it will also take long time in case of corrupt connection string.
I aim to detect the corrupt connection string before doing any critical operation.
You want to predict if it is possible to connect to your database. Well, this is not possible. There is no way to know if you will connect until you try to. Connection to the db may fail for various reasons:
DB Server is not responding, because SqlServer is down.
The server computer is down (power failure, for example).
The server you connect to does not exist.
The server exists, but you connect on wrong port.
The database refuses connection because you are not authorized.
The db server is busy and responds very slowly.
The network is bad / busy and data is transmitted very slowly.
The server is there, but configured in such a way that it refuses your connection. For example, it wants TCP, but you try named pipes.
And many more. It is absolutely impossible to validate against all these.
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 write simple ASP.NET Core app where Controller injects MyService (configured as Scoped) that in turn injects MyDbContext.
In my controller's method I have 2 database queries and my debug output looks like this:
Executing action method...
Opening connection to database 'shell' on server 'tcp://127.0.0.1:5432'.
...
Closing connection to database 'shell' on server 'tcp://127.0.0.1:5432'.
Opening connection to database 'shell' on server 'tcp://127.0.0.1:5432'.
...
Closing connection to database 'shell' on server 'tcp://127.0.0.1:5432'.
Request finished in...
The question is: Is it correct to open a new connection on each request and even more - to open a new connection for each sql command? Can't it establish the connection to database once and reuse it. Wouldn't it be much better for performance?
PS: I use PostgreSQL with npgsql provider
Like someone else mentioned. Connection pooling is your friend.
The opening and closing is perfectly fine.
https://stackoverflow.com/a/4439434/3799142
Always open and close the connection as already mentioned all over SO. Connection pooling deals with your performance issues.
Makes your code easier to read and you will never have to worry about, where is that connection i have to open, is it open? Isn't it closed somewhere else?
As you are asking, I assume you dont really want to. This is what I generally do. A small wrapper method which would fire your sql commands simmilar to this.
static bool FireCommand(SqlCommand command)
{
command.Connection.Open();
command.ExecuteQuery();
command.Connection.Close();
}
I am using a linked server to update records in AS/400. It isn't closing the connections properly. On the AS/400 side there are still a number of connections idle. In the sql log it is showing:
EXCEPTION_ACCESS_VIOLATION writing address 0000000000000024 at 0x0000000077BDE4B4
It doesn't appear that it is every time we open a connection and update the file on the AS/400 side. We updated 222 records and there were still 210 connections open. I would expect there to be 222.
We are calling a stored procedure from a .NET app. In the stored procedure we are executing:
EXECUTE (#as400Query) at S100405D
Where the as400Query is a string with the update statement and S100405D is the linked server. The records are getting updated in the AS/400, so that isn't an issue. Just seems that when trying to close the connections, there is an error. Also I checked the settings on the linked server and the connection timeout = 0 (off). Not sure if setting a timeout will close them, or it won't matter because it is throwing an error anyways.
Any help would be greatly appreciated!
Brian
are you submiting any sort of code to close the connection on the AS side? SQL server will only close its connecion, any other connection opened on any other RDBMS won't be managed by SQL
As an IBM i programmer, I would not expect to see any errors during a stored procedure call. Rarely, the OS will throw an exception if there is a parameter mis-match. The most common is the caller (C#) using VARCHAR and the IBM side declaring it as CHAR.
Aside from that, have the IBM people make sure they are current on PTFs.
As a style matter, I would not expect to see:
open connection
CALL proc
close connection
for each row to be updated. Rather, I would expect
open connection
loop
CALL proc
end loop
close 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