Hello everyone i was hopping to get a little advice on how someone would go about doing something
i need to test sql connection for a main server, if the connection returns false then i need to set a variable that will tell the program to use it own local sql ce database
how would yall go about testing that connection then setting that variable?
Would yall agree on something like this
try
{
con.open();
standalone=false;
con.close();
}
catch
{
standalone=true;
con.close();
}
Not the best solution, but if you have a bunch of queries would be ok. Whenever you need to open a connection to your object you check if everything is ok with your first connection string. Otherwise your second conneciton string.
using (SqlConnection Conn = new SqlConnection(connectionString1))
{
try
{
Conn.Open();
// Here goes your statements for querying your db.
}
catch (Exception Ex)
{
using(SqlConnection Conn2 = new SqlConnection(connectionString2))
{
try
{
Conn2.Open();
// Here goes your statements for querying your db.
}
catch(Exception Ex2)
{
// Here goes your error handling code for the second connection
}
}
}
}
Although the above might be a solution to your problem, I should state a concern, which have arisen since I read your question. Suppose you connect to your first database and you do any tranasction you need with it. After a little time there comes a problem and you cannot connect to your first db. So you will connect to your second db. Then the data of the second db will be incosistent with the data you had, when you were using the first db.
You need to handle sqlexception and if one occurs you can then use your local connection
see http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.open(v=vs.110).aspx
Related
I have a C# application that reads/writes from/to an Access Database. I do this using an OleDbConnection.
Before a read / write, I want to check that my database connection is open. It should be straight-forward....
if (Connection.State != ConnectionState.Open) Connection.Open();
While this generally works well, it is not working for situations where network access is interrupted. The Connection.State is still recorded as 'Open', so I'd get an exception. So, I tried this:
Connection.ResetState();
if (Connection.ConnectionState(DatabaseType) != ConnectionState.Open) Connection.Open();
Nope... That's not working either, as the ResetState() method isn't actually resetting the state.
So I tried this extension method (a bit ugly...)
public static ConnectionState ConnectionState(this OleDbConnection connection, DatabaseType type)
{
connection.ResetState();
if (type == DatabaseType.Access)
{
//Reset state might not work... Check that the datasource is locatable
if (!File.Exists(connection.DataSource)) return System.Data.ConnectionState.Closed;
return connection.State;
}
return connection.State;
}
This "sort of" works, in that it correctly identifies that the DataSource can't be located. But then I get an exception when I try to open the database; not that it can't be found, but that its an invalid operation trying to open a connection that is already open!
I've spent about an hour trying to google to find a reliable way to get the true status of the database connection. Any other suggestions?
Correct way to use DbConnection is to create a new one for every command. Connection pooling means there is not usually a big overhead, and any network issues in between are sorted out automatically.
Make sure to Dispose correctly.
I am using ODP.NET for my MVC project and keep getting "-1000 Connection Request Timeout Error" when the Database goes down and then comes back up again. It starts working as soon as I recycle IIS AppPool. I tried to use ClearAllPool(), ClearPool(connection) inside the catch block to remove the error connection but both didn't work. I found a post on StackOverflow to use Fast Connection Failover by adding HA events=true in the connectionstring. I tried that too but no luck. I asked DBA and they said the feature is ON the server-side by default. I don't know why ODP.NET is still using an old invalid connection created when the database was down even if database is up and running? All of my code is also wrapped inside a using block which will close/dispose connection. My Oracle.DataAccess version is 12.1.0. I read every page on google about the connection pooling, FCF but nothing helped.
my connectionstring is as follow:
<add name="XXX"; providerName="Oracle.DataAccess.Client"; connectionString="DataSource=XXX;username=xxx;password=XXX;Pooling=True;Connection Timeout=120; Connection LifeTime=120; Validate Connection=True; Min Pool size=1;Max Pool size=180; HA events=true; Incr Pool size=5; Decr Pool size=2;"/>
here is my oracle connection code:
using(OracleConnection conn= new OracleConnection(connectionstring))
{
try
{
OracleCommand cmd=new OracleCommand("storedprocedure",conn)
{CommandType=CommandType.StoredProcedure};
//add parameters to command
foreach(var parmeter in parameters)
{
cmd.Parameters.Add(parameter);
}
conn.Open(); // this is where exception occurs
cmd.ExecuteNonQuery();
}
catch(OracleException ex)
{
if(conn.State=ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
//log exception ex in logfile
}
if(conn.State=ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
//Dispose All Parameters using Dispose() outside using statement.
foreach(var parmeter in parameters){
parameter.Dispose();
}
The only solution work is when I set Pooling=False, which we don't want to do.
I played with these connectionstring properties like increase Min pool size, increase connection Lifetime etc. but nothing seems to be working.
I will really appreciate any help here.
Thank you.
Try this and tell me if you still have this issue
using(OracleConnection conn= new OracleConnection(connectionstring))
using(OracleCommand cmd=new OracleCommand("storedprocedure",conn))
{
cmd.CommandType=CommandType.StoredProcedure;
foreach(var parmeter in parameters)
{
cmd.Parameters.Add(parameter);
}
conn.Open(); // this is where exception occurs
cmd.ExecuteNonQuery();
}
if error is not desired put this entire block into try/catch
sc is a SQL connection passed in from the calling function
I'm using one SQL connection throughout my entire program and having each subfunction open and close it as needed. (I read this was fine, because the SQLConnection class has it's own connection pooling functionality)
string q = "this would be a query";
using (SqlCommand cmd = new SqlCommand(q, sc))
{
cmd.Parameters.Add("#ID", SqlDbType.Int);
cmd.Parameters["#ID"].Value = (an id that is passed in);
try
{
sc.Open();
using (var reader = cmd.ExecuteReader())
{
if(reader.read())
{ logic that might throw exception }
else
{ logic that might throw exception }
}
sc.Close();
}
catch (Exception e)
{
alert user, program does not halt but current function returns
}
}
So the connection opens and the command attempts to execute and some logic is performed that might throw an exception. (I'm not expecting it to) This function is part of a larger program that is processing a large dataset. If it fails DUE TO AN EXCEPTION it needs to note it, but it also needs to attempt to keep running.
Other parts of the program are sharing this connection and opening and closing it as they need it and I've used this basic template for all queries in the program.
It just occurred to me that if an exception occurred, the connection might not be closed. Am I correct in thinking that? My original concern when writing this is that the sc.Open() would be the thing that would throw an exception, but as I've used this in multiple places I've realized that this was short sighted because the connection could open and then any number of steps between the close could throw an exception.
Do I need additional logic here to make sure this connection is closed and the program can attempt to continue running?
If my understanding is correct that the connection needs to be closed in the event of an exception between the open and close I think I have 2 options :
try/catch between the open and close
sc.Close() in the catch block (Bonus concern : If the sc.Open() throws an exception and catch block tries to sc.Close() will an additional exception be thrown?)
You do not need to worry about closing the connection. The connection is closed automatically when it disposed by the using statement within which the connection is created.
In the event of an exception, the connection will still be disposed (and thus closed) because that's how a using statement is designed to work.
You have the State property of the SqlConnection that you can use to determine what state the last network operation left the connection in. This property is described here: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.state(v=vs.110).aspx
I would recommend reacting to exceptions in the SqlConnection (such as Open) and in the SqlCommand separately, because, in my experience, you will usually want to take different actions. Even with the overall approach you want to take,
if you can't open your connection, there is no point in preparing the query,
and you likely want to say something different about inability to open the connection than you would if the query failed. I would move the sc.Open() before the creation of the SqlCommand and try/catch around that.
Clarification on the above answer by #roryap - there is no need for sc.Close() if your connection is created in a using statement but from your question I guess it's not. In which case you should probably add a finally section to the try catch block and close the connection in there.
Its better that you close the connection in finally block
finally
{
sc.Close();
}
After try block is completed, the finally block will work.
In a case of an exception, finally block also works.
So the connection will closed in any case.
I am working on a new project and have a section of code where I don't want to actually handle exceptions but make sure any DB connections are closed. I am wondering which will be the best way to handle the issue. I see 2 ways but am not sure which will be clearer:
SqlConnection con = new SqlConnection(connectionstring);
try
{
con.open()
//DoStuff
}
catch(Exception)
{
throw;
}
finally
{
con.close();
con.dispose();
}
OR
try
{
con.open()
//DoStuff
}
finally
{
con.close();
con.dispose();
}
Either way I pass the exception up to the calling code to be handled but still clean up the connections.
You can use using statement to enclose your connection. It would translate into try-finally block, like in your second code example.
Since you are not doing anything with your exception (like logging) you can leave out the catch block.
You can use using like:
using (SqlConnection con = new SqlConnection(connectionstring))
{
}
This will ensure your connection is disposed at the end of using block, even in case of an exception. You can only use using statement with those objects which implements IDisposable interface.
If you are going to deal with objects which doesn't implement IDisposable then your second code snippet (With try-finally) is good enough, since you want the exception to bubble up.
Let's assume i got this code:
internal static bool WriteTransaction(string command)
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
try
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(command, conn))
cmd.ExecuteNonQuery();
}
catch { return false; }
}
return true;
}
Well, i have placed conn's using outside the try/catch clause because SqlConnection's constructor will not throw any exception (as it says). Therefore, conn.Open() is in the clause as it might throw some exceptions.
Now, is that right coding approach? Look: SqlCommand's constructor does not throw exceptinos either, but for the code reduction i've placed it along with cmd.ExecuteNonQuery() both inside the try/catch.
Or,
maybe this one should be there instead?
internal static bool WriteTransaction(string command)
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
try { conn.Open(); }
catch { return false; }
using (SqlCommand cmd = new SqlCommand(command, conn))
try { cmd.ExecuteNonQuery(); }
catch { return false; }
}
return true;
}
(sorry for my english)
Unless you can handle the exception in some meaningful way, do not catch it. Rather, let it propagate up the call-stack.
For instance, under what conditions can a SqlCommand ExecuteNonQuery() throw exceptions? Some possibilities are sql query that is improperly formed, cannot be executed or you've lost connection to the database server. You wouldn't want to handle these all the same way, right?
One exception you should consider handling is the SQLException deadlock (erro number 1205).
As was pointed out in a comment, at the very minimum you should be logging exceptions.
[BTW, WriteTransaction() is probably a poor name for that method, given the code you have shown.]
Your first code sample, with a single try-catch block, is equivalent to the second. The first one is, however, easier to read and shorter.
It's worth bearing in mind that the usual C# coding approach is not to catch exceptions except at the very top layer of your code.
A well-written reference on this is here: http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx.
In your case this will simplify your code: instead of returning a bool to indicate that the method succeeded or failed, then testing for this, you "assume for the best" by making the method void and merely handle unexpected exceptions at a top level exception handler.
Exception handling for writing to databases can be considered a slight exception to this general rule: but my personal approach would be to trap specifically for concurrency issues and if that happens retry a few times.
I think your first solution is better because if you get an error establishing connection is not useful trying to execute a command on that connection.
So with first solution if you get an error you go directly do catch block and then dispose objects, while with the second you go through two exceptions, overloading memory useless.
with good catch clause (exceptions logging) you don't realy need 2x try block, 1 is enough
...
your second approach is wrong - there's no need to try catch openning connection - becouse even if you catch this you are done anyway - you can't execute query. In your catch block you could try to "repair" that problem, but what would it give you - while loops in catch ?
Your first approach is the preferable one, for a very simple reason: The two versions of the method are identical in terms of behavior, but the first one needs less code.
Sometimes it's as simple as counting lines of code ;-)...
HTH!
P.S.
I wouldn't have a try/catch statement in this method at all, but I would place it on a higher level, where this internal method is invoked.
Given your method 'WriteTransaction' is swallowing all exceptions and returning the success of the transaction, or not, then I would use one try/catch block around the entire method.
internal static bool WriteTransaction(string command) {
try {
using (SqlConnection conn = new SqlConnection(SqlConnectionString)) {
conn.Open();
using (SqlCommand cmd = new SqlCommand(command, conn)) {
cmd.ExecuteNonQuery();
}
}
}
catch {
return false;
}
return true;
}
Now you should ask yourself if catching all exceptions and returning true/false is the right thing to do. When in production how are you going to diagnose and fix errors if you haven't at least logged the exception?