I am getting Timeout expired error - c#

System.Data; Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
this error will come only when i run service
i am using below code
try
{
LogGenerator.WriteErrorLog("Conn opened before");
if (con.State == System.Data.ConnectionState.Closed)
con.Open();
LogGenerator.WriteErrorLog("Conn opened");
// Set up a command with the given query and associate
// this with the current connection.
SqlCommand cmd = new SqlCommand("Backup database " + DBName + " to disk='" + filePathExist + "'", con);
cmd.ExecuteNonQuery();
LogGenerator.WriteErrorLog("query executed");
}
catch(Exception ex)
{
LogGenerator.WriteErrorLog("Error in Conn");
LogGenerator.WriteErrorLog(ex);
}
finally
{
con.Close();
con.Dispose();
SqlConnection.ClearPool(con);
}

As your trying take DB backup sometime it will take more than default connection time, so try to set timeout to your command.
try
{
if (con.State == System.Data.ConnectionState.Closed)
con.Open();
// Set up a command with the given query and associate
// this with the current connection.
SqlCommand cmd = new SqlCommand("Backup database " + DBName + " to disk='" +
filePathExist + "'", con);
cmd.CommandTimeout = 60;
cmd.ExecuteNonQuery();
}
catch(Exception ex)
{
//handle exception here
}
finally
{
con.Close();
con.Dispose();
SqlConnection.ClearPool(con);
}
for more information on timeout please refer here.
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout(v=vs.110).aspx
https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-remote-login-timeout-server-configuration-option

Related

How to run 2 successful actions at same time?

Goal:
My goal is to create a MySQL query using C#, and on successful query I'd like to use File.Copy... and vice versa.
This is my current code:
//Try run code
try
{
//Add record to MySQL
using (var conn = new MySqlConnection(ConnectionString.ConnString))
{
using (var cmd = new MySqlCommand("INSERT INTO files (document_name, path, version, section, user_modified, date_modified)" +
" values (#doc, #path, #version, #section, #user, NOW());", conn))
{
conn.Open();
cmd.Parameters.AddWithValue("#doc", docName.Text);
cmd.Parameters.AddWithValue("#path", $"{finalPath}Section {Section.Text}\\{docName.Text}{Path.GetExtension(fileName)}");
cmd.Parameters.AddWithValue("#version", versionNumber.Text);
cmd.Parameters.AddWithValue("#section", Section.Text);
cmd.Parameters.AddWithValue("#user", UserDetails.userId);
cmd.ExecuteNonQuery();
}
}
//Copy file into new directory
File.Copy(fileName, $"{finalPath}Section {Section.Text}\\{docName.Text}{Path.GetExtension(fileName)}");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
Question:
What is a good method to achieve the following..
If MySQL query not successful then do not do anything and stop and return to where the error was.
If MySQL query was successful and File.Copy wasn't (Ran into an error for any reason) - then recover the query, delete whatever was inserted and go back all the way to step one.
How can this be achieved?
Edit 10/06/2020
I have managed to get the following code :
//Try run MySQL query with roll back function if failed.
public void RunTransaction(string myConnString)
{
MySqlConnection myConnection = new MySqlConnection(ConnectionString.ConnString);
myConnection.Open();
MySqlCommand myCommand = myConnection.CreateCommand();
MySqlTransaction myTrans;
// Start a local transaction
myTrans = myConnection.BeginTransaction();
// Must assign both transaction object and connection
// to Command object for a pending local transaction
myCommand.Connection = myConnection;
myCommand.Transaction = myTrans;
try
{
myCommand.CommandText = "INSERT INTO files (document_name, path, version, section, user_modified, date_modified, review_date)" +
" values (#doc, #path, #version, #section, #user, NOW(), NOW() + interval 12 month);";
myCommand.Parameters.AddWithValue("#doc", docName.Text);
myCommand.Parameters.AddWithValue("#path", $"{finalPath}Section {Section.Text}\\{docName.Text}{Path.GetExtension(fileName)}");
myCommand.Parameters.AddWithValue("#version", versionNumber.Text);
myCommand.Parameters.AddWithValue("#section", Section.Text);
myCommand.Parameters.AddWithValue("#user", UserDetails.userId);
myCommand.ExecuteNonQuery();
myTrans.Commit();
}
catch (Exception e)
{
try
{
myTrans.Rollback();
}
catch (MySqlException ex)
{
if (myTrans.Connection != null)
{
Console.WriteLine("An exception of type " + ex.GetType() +
" was encountered while attempting to roll back the transaction.");
}
}
Console.WriteLine("An exception of type " + e.GetType() +
" was encountered while inserting the data.");
Console.WriteLine("Neither record was written to database.");
}
finally
{
myConnection.Close();
}
}
Question..
How would I then implement the File.Copy function to suit my goal?
I have this source.. https://learn.microsoft.com/en-us/dotnet/api/system.io.fileinfo.copyto?view=netcore-3.1
but not sure where to code in my current code?

The timeout period elapsed prior to obtaining a connection from pool

I have problem with my homework code. We must create some database with updating users, but I am getting error with these and program crash..
This is full error code and there is code..
Error: MySql.Data.MySqlClient.MySqlException (0x80004005): error
connecting: Timeout expired. The timeout period elapsed prior to
obtaining a connection from the pool. This may have occurred because
all pooled connections were in use and max pool size was reached.
I try with query.CommandTimeout = 60; but i think its useless, what do u think?
MySqlConnection connect = new
MySqlConnection("Server=localhost;Database=Work;Uid=root;Pwd='1234';");
connect.Open();
MySqlCommand query = new MySqlCommand(#"UPDATE user
SET User_Name=#User_Name,User_BankBalance=#User_BankBalance,
User_Password=#User_Password,LottoTimer=#LottoTimer
WHERE User_Name='" + Escape(u.Username) + "'", connect);
using (query)
{
query.CommandType = System.Data.CommandType.Text;
query.Parameters.AddWithValue("#User_Name", Escape(u.Username));
query.Parameters.AddWithValue("#User_BankBalance", u.BankBalance);
query.Parameters.AddWithValue("#User_Password", u.Password);
query.Parameters.AddWithValue("#LottoTimer", u.LottoTimer);
query.Dispose();
query.Prepare();
query.ExecuteNonQuery();
}
connect.Close();
return;
You method should look something like this:
string query =
#"UPDATE user SET"
+ " User_Name=#User_Name,"
+ " User_BankBalance=#User_BankBalance,"
+ " User_Password=#User_Password,"
+ " LottoTimer=#LottoTimer"
+ " WHERE User_Name='" + Escape(u.Username) + "'";
using( var connect = new MySqlConnection("Server=localhost;Database=Work;Uid=root;Pwd='1234';"))
using( var query = new MySqlCommand(query, connect))
{
connect.Open();
query.CommandType = System.Data.CommandType.Text;
query.Parameters.AddWithValue("#User_Name", Escape(u.Username));
query.Parameters.AddWithValue("#User_BankBalance", u.BankBalance);
query.Parameters.AddWithValue("#User_Password", u.Password);
query.Parameters.AddWithValue("#LottoTimer", u.LottoTimer);
query.Prepare();
query.ExecuteNonQuery();
}
return;
It is important to dispose the MySqlConnection, so it can be available to the pool again. The problem you have is that all connections are used in the pool, and it is waiting for one - until the timeout.

No process is on the other end of the pipe exception when restoring database

When I attempt to restore my backup database it restores the database successfully but when log out the system it gives me the exception"A transport-level error occured when sending the request to the server. (Provider:Shared memory provider, error 0-No process is on the other end of the pipe)" ... how this can be solved
My codes for restoring database are:
private void restoreBtn_Click(object sender, EventArgs e)
{
string database = cn.Database.ToString();
try
{
cn.Open();
string sqlres1=string.Format("ALTER DATABASE ["+database+"] SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
SqlCommand command1=new SqlCommand(sqlres1,cn);
command1.ExecuteNonQuery();
string sqlres2 = "USE MASTER RESTORE DATABASE ["+database+"] FROM DISK='"+restoretxt.Text+"' WITH REPLACE";
SqlCommand command2 = new SqlCommand(sqlres2, cn);
command2.ExecuteNonQuery();
string sqlres3 = string.Format("ALTER DATABASE [" + database + "] SET MULTI_USER");
SqlCommand command3 = new SqlCommand(sqlres3, cn);
command3.ExecuteNonQuery();
MessageBox.Show("Database restore done successfully");
this.Close();
}
catch(SqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
cn.Close();
}
}

SqlCommand state closed when SqlConnection state is open

I am having an intermittent issue with a SqlDataRreader class where I have opened a SqlConnection and its state is OPEN, but when I create a SqlCommand with that SqlConnection, the SqlConnection's state is CLOSED. This only occurs approximately 1 in 10 attempts, and so it might be a timing issue.
Note that rather than putting the connection in a Using block, I open/close the connection independently as I usually execute multiple commands at once, however the issue usually occurs on the first time a command is executed on a connection that has just been opened.
The connection code is:
private SqlConnection sql;
public Result Connect(string database)
{
string connection = Config.environments[Config.environment][database];
try
{
// Create and open the connection
sql = new SqlConnection(connection);
sql.Open();
if (sql == null || sql.State != System.Data.ConnectionState.Open)
return new Result(false, "Connect to Database", "Could not connect to database [" + connection + "]");
return new Result(true, "Connect to Database", "Connected to database [" + connection + "]");
}
catch (Exception e)
{
return new Result(false, "Connect to Database", "Could not connect to database [" + connection + "] " + e.ToString());
}
}
The run command code is:
private DataTable RunSql(string statement)
{
if (sql == null || sql.State != System.Data.ConnectionState.Open)
throw new ScriptException("Cannot execute SQL command, no database connection established [" + statement + "]");
// Create and execute the SQL statement
using (SqlCommand command = new SqlCommand(statement, sql))
{
command.CommandTimeout = Config.sqlTimeout;
try
{
using (SqlDataReader reader = command.ExecuteReader()) // ERROR OCCURS HERE! - sql.State is OPEN, but command.State is CLOSED ???
{
// Check is the reader has any rresults
if (reader.HasRows)
{
DataTable data = new DataTable();
data.Load(reader);
return data;
}
else
{
throw new Exception("No results found for statement: " + statement + ", on server: " + sql.DataSource + ", in database: " + sql.Database);
}
}
}
catch (SqlException)
{
//Log things here
}
throw new ScriptException("Error executing sql command: " + statement);
}
}
The code that reproduces the issue (occasionally):
private DataTable RunSingleCommand(string database, string command)
{
Log(Connect(database));
return RunSql(command);
}
What I can suggest is inside the Connection command before opening the connection , give a condition check to know whether the connection is currently open or not. Only if its in closed mode open the new connection
try
{
// Create and open the connection
sql = new SqlConnection(connection);
if (sql.State != System.Data.ConnectionState.Open)
{
sql.Open();
}
return new Result(true, "Connect to Database", "Connected to database [" + connection + "]");
}
catch (Exception e)
{
return new Result(false, "Connect to Database", "Could not connect to database [" + connection + "] " + e.ToString());
}

Data being duplicated in a database on save

I am trying to save some data in a database using an INSERT query but it is saving double value on single click. For example I save 'Lahore', it'll save it two times:
Lahore
Lahore
SqlConnection conn = new SqlConnection("Data Source = HAMAAD-PC\\SQLEXPRESS ; Initial Catalog = BloodBank; Integrated Security = SSPI ");
try
{
conn.Open();
SqlCommand query = new SqlCommand("insert into City values('" + txtCity.Text + "')", conn);
query.ExecuteNonQuery();
SqlDataReader dt = query.ExecuteReader();
if (dt.Read())
{
MessageBox.Show("Saved....!");
}
else
{
MessageBox.Show("Not saved.....");
}
}
catch (Exception ex)
{
MessageBox.Show("Failed....." + ex.Message);
}
Your code is doing exactly what you told it to.
If you call an Execute*() method twice, it will run your query twice.
It's saving twice because you are executing the query twice:
query.ExecuteNonQuery();
SqlDataReader dt = query.ExecuteReader();
You are saving twice.
The executeNonQuery will return the number of rows affected so use this instead.
SqlConnection conn = new SqlConnection("Data Source = HAMAAD-PC\\SQLEXPRESS ; Initial Catalog = BloodBank; Integrated Security = SSPI ");
try
{
conn.Open();
SqlCommand query = new SqlCommand("insert into City values('" + txtCity.Text + "')", conn);
var rowsAffected = query.ExecuteNonQuery();
if (rowsAffected == 1)
{
MessageBox.Show("Saved....!");
}
else
{
MessageBox.Show("Not saved.....");
}
}
catch (Exception ex)
{
MessageBox.Show("Failed....." + ex.Message);
}

Categories