C# SqlTransaction.Commit throw exception because Connection is null - c#

I have a problem using SqlTransaction. Here's the code
SqlConnection conn = new SqlConnection(connectionString);
// assume that at this point I add try/catch and the connection is successfully opened.
conn.Open();
SqlTransaction trans = conn.BeginTransaction(IsolationLevel.RepeatableRead);
//.........
// Here I do my action with database, change it, commit, call ExecuteNonQuery, //ExecuteScalar,etc...
// And after that long processing with this transaction, I don't know why trans.Connection //is null. and therefore when I call trans.commit(), an exception was raised?
trans.commit();
Does anybody have any clues?
I assume this might be because of memory of database server was ate up because of too much connections. But I'm not sure.
How can I resolve this?

make use of using
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
Console.WriteLine("State: {0}", connection.State);
}

Seems like typo
con.BeginTransaction(IsolationLevel.RepeatableRead)
should be
conn.BeginTransaction(IsolationLevel.RepeatableRead)

use a using statement:
using (SqlConnection connection = new SqlConnection(connectionString))
{
//your code here
}

c# - SqlTransaction after catch transaction connection is null - Stack Overflow
SqlTransaction after catch transaction connection is null
Edyn said that:
Ran into a similar issue. In my case it was happening for a specific SqlException. Most exceptions would be caught and handled just fine, but whenever I got a conversion error (such as trying to convert a string to a number) it would automatically end the transaction.
In my solution, I rebuild the transacton if found the underlying connection is null. But it's a dirty work.

Related

Does a SQL connection close with "using" if the connection comes from a static class?

Am I closing my SQL connection correctly, by placing it inside a "using" block?
This is how I grab a new connection, execute a query, and return the results:
using (SqlConnection objCS = DB.LMSAdminConn())
{
objCS.Open();
SqlCommand objCommand = new SqlCommand("SELECT TOP 1 * FROM users WHERE userid = #userid", objCS);
objCommand.Parameters.Add("#userid", SqlDbType.Int).Value = userid;
SqlDataReader reader = objCommand.ExecuteReader();
while (reader.Read())
{
//do something
}
reader.Close();
}
The connection itself comes from this call:
public static SqlConnection LMSAdminConn()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["lmsadmin"].ToString());
}
I am opening the connection inside a "using" block, and I thought that the connection would be closed as well, because it is opened inside the "using" block. But since the "new SqlConnection" object is actually generated from an outside class, is my connection still getting appropriately closed? SQL Server shows the connection as still being open, but I'm not sure if that is ADO.NET connection pool recycling / sharing, or if the connection is truly being held open. I don't explicitly call .Close() on the connection inside the "using" block.
Do I need to explicitly close the SqlCommand and SqlDataReader objects as well, or are they disposed when we leave the "using" block as well?
A using block is essentially syntactic sugar for having a try/finally block that calls the Dispose method of the object it is acting on, it doesn't matter where that object was created.
For a SqlConnection object, calling Dispose will close the connection. From the docs:
If the SqlConnection goes out of scope, it won't be closed. Therefore, you must explicitly close the connection by calling Close or Dispose. Close and Dispose are functionally equivalent.
Yes, it will close the connection once it loses scope.
Sample:
using (SqlConnection sqlConn = new SqlConnection("myConnectionString"))
{
sqlConn.Open();
...
}
This code will be converted into the following by the compiler :
try
{
SqlConnection sqlConn = new SqlConnection("myConnectionString");
sqlConn.Open();
...
}
finally
{
sqlConn.Close();
}
As you can see the close() is called in the finally block.
This finally block will force close the connection even if there is an exception during run-time within the using block.
You had an idea about connection pools - this is the right idea!
ADO.NET it is so beautiful that it tries to optimize everything and store it in connection pools. But we still need to always close connections!

SQL Server: "CREATE DATABASE" query timeout

I have a .Net application that is creating a new database. The current code is working great in development environment and in many production environments. So I am confident the code is fine.
However, we have a specific instance where the user is getting a timeout while the application is running the following SQL Command:
CREATE DATABASE NameOfDatabase
The code is pretty simple, and as you can see it uses the default timeout period for SQL commands which is 30 seconds:
using (SqlConnection connection = new SqlConnection(connectionString))
{
string query = "CREATE DATABASE " + databaseName;
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
command.ExecuteNonQuery();
}
Note: our log file shows the error occurs on ExecuteNonQuery which suggests that this is NOT a timeout while opening the connection, and rather during query execution.
The specific .Net error is:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
With a line from the stack trace to show my reasoning on it being a command timeout (not a connection timeout):
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
Note: This error information is obtained using a try/catch around the code which was left out of the question for simplicity as it is not relevant to the problem.
Questions
Under any reasonable (or even uncommon) situations, should a CREATE DATABASE query take this long to run and still be successful?
If it shouldn't take that long, what are the common causes for a timeout? (where should I be looking to debug the problem?)
I do not have enough rep points to comment. To get the specific error wrap command.ExecuteNonQuery(); in a try catch. at least you can get the specific error that is occurring. Also use using with SqlCommand that will dispose that object. Connection State
using (SqlConnection connection = new SqlConnection(connectionString))
{
string query = "CREATE DATABASE " + databaseName;
using(SqlCommand command = new SqlCommand(query, connection))
{
try
{
connection.Open();
if (connection.State == ConnectionState.Open)
command.ExecuteNonQuery();
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
}
Maybe this TechNet article can help? Troubleshooting: Timeout Expired

C# Closing Database Connections

I need a to get a bit of understanding in this, When you open a connection to a Database can you leave it open?
How does this connection close?
Is it good practise or bad practice?
Currently I have a request to a database that works no problem
oCON.Open();
oCMD.ExecuteNonQuery();
oCON.Close();
However Some of the examples that I have seen are something like this with no database close.
oCON.Open();
oCMD.ExecuteNonQuery();
How would this connection get closed?
Is this bad practice?
I was looking for a duplicate, as this seems to be a common question. The top answer I found is this one, however, I don't like the answer that was given.
You should always close your connection as soon as you're done with it. The database has a finite number of connections that it allows, and it also takes a lot of resources.
The "old school" way to ensure the close occurred was with a try/catch/finally block:
SqlConnection connection;
SqlCommand command;
try
{
// Properly fill in all constructor variables.
connection = new SqlConnection();
command = new SqlCommand();
connection.Open();
command.ExecuteNonQuery();
// Parse the results
}
catch (Exception ex)
{
// Do whatever you need with exception
}
finally
{
if (connection != null)
{
connection.Dispose();
}
if (command != null)
{
command.Dispose();
}
}
However, the using statement is the preferred way as it will automatically Dispose of the object.
try
{
using (var connection = new SqlConnection())
using (var command = new SqlCommand())
{
connection.Open();
command.ExecuteNonQuery();
// Do whatever else you need to.
}
}
catch (Exception ex)
{
// Handle any exception.
}
The using statement is special in that even if an exception gets thrown, it still disposes of the objects that get created before the execution of the code stops. It makes your code more concise and easier to read.
As mentioned by christophano in the comments, when your code gets compiled down to IL, it actually gets written as a try/finally block, replicating what is done in the above example.
You want your SqlConnection to be in a using block:
using(var connection = new SqlConnection(connectionString))
{
...
}
That ensures that the SqlConnectionwill be disposed, which also closes it.
From your perspective the connection is closed. Behind the scenes the connection may or may not actually be closed. It takes time and resources to establish a SQL connection, so behind the scenes those connections aren't immediately closed. They're kept open and idle for a while so that they can be reused. It's called connection pooling. So when you open a connection, you might not really be opening a new connection. You might be retrieving one from the connection pool. And when you close it, it doesn't immediately close, it goes back to the pool.
That's all handled behind the scenes and it doesn't change what we explicitly do with our connections. We always "close" them as quickly as possible, and then the .NET Framework determines when they actually get closed. (It's possible to have some control over that behavior but it's rarely necessary.)
Take a look at the Repository Pattern with Unit of Work.
A connection context should be injected into the class which operates commands to the database.
A sql execution class - like a repository class represents - should not create a connection. It is not testable and hurts the paradigm of SRP.
It should accept an IDbConnection object like in the constructor. The repository should not take care if behind the IDbConnection is an instance of SqlConnection, MysqlConnection or OracleConnection.
All of the ADO.NET connection objects are compatible to IDbConnection.

Testing Database Connectivity in C# Console Application

I have a C# Console Application that is essentially a long batch process that processes data on a nightly basis across many different databases. What is the proper or preferred way to test basic database connectivity at the beginning of this type of program? I ran into the issue of having an expired database password for one of my connections that was caught by exception handling but I want to test for basic connectivity at the very beginning.
Would a simple SELECT query suffice or is there a more efficient way of doing this for numerous databases?
IMHO the simplest way is trying to connect to database and, if you have a failure, you give up.
As you're running a night batch, it's not important to understand immediately the reason and solve it.
So something like this
using(SqlConnection conn = new SqlConnection(connectionString))
{
try
{
conn.Open();
// Do what you please here
}
catch (Exception ex)
{
// Write error to file
File.Append(...,
DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + " " +
ex.Message);
}
finally
{
conn.Close();
}
}
Next morning you can check file for errors...
'Connection.open`
is the simple way to determine if you can connect to db or not.
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
}
If you get a SqlException with number 18487 or 18488 it indicates the password has been changed.
Connection.changePassword
You don't need to run any query.
If you use SqlConnection passing the connection string, you can just try to Open() the connection and you'll get an exception if you cannot connect
Something like:
try
{
var cnn = new SqlConnection(connectionString);
cnn.Open();
}
catch
{
// connection failed, do something
}
Opening (and then closing) a connection should be sufficient to test the password. however, this does not tell you , if a db-user has permissions to access specific tables.

ado.net Closing Connection when using "using" statement

I am doing my database access methods to SQL Server like this
using (SqlConnection con = new SqlConnection(//connection string)
{
using (SqlCommand cmd = new SqlCommand(storedProcname, con))
{
try{
con.open();
//data reader code
}
catch
{
}
}
}
Do I need to be closing or disposing of SqlCommand, or will the using statement take care of that for me? I just don't want connection hanging open
Thanks
The using will take care of it for you. Under the hood, SqlConnection.Dispose() calls the SqlConnection.Close() method, and SqlCommand.Dispose() calls SqlCommand.Close().
As additional background, a using statement is syntactic sugar for a try ... finally that disposes the IDisposable object in the finally.
As an aside, you can make the code more concise and readable as follows:
using (SqlConnection con = new SqlConnection(/*connection string*/))
using (SqlCommand cmd = new SqlCommand(storedProcname, con))
{
//...
}
As Phil said, the using clause will take care of it for you. When compiled down it wraps the connection create in a try .. finally and places the connection disposal call inside the finally.
For more information you can see the using statement article at msdn.
Yes your code will close the connection, however that typcally means release back to the connection pool to be truely closed later.
If you execute this snippet of code, and then do an sp_who and observe that your connection is still there, that would be why.
If you absolutely need the connection truely closed (an edge case to be sure) then use the ClearAllPools
static method of ths SqlConnection
Using keyword will automatically close the connection for you
so you don't need to worry about calling connection.close() at the end every time.
when the scope
using (SqlConnection con = new SqlConnection(//connection string)
{
}
will over , connection will automatically be disposed by runtime. so don't worry
I think "using" was not required for SqlCommand. "Using" for SqlConnection would have done the job for you alone.
In fact you connection is submitted to Connection pool.

Categories

Resources