简体   繁体   中英

C# - create has been successful, adding qty has been successful. but error apears 'the connection is already open.'

guys..

I am training to create an existing bookstore app feature to add book stock and reduce book stock. when I create a stock added feature and save the transaction data of the stock addition, I get an error 'the connection is already open.' but I've closed all open connections. Please help me..

this is my code to show distributor id

public void loadDistributorID()
    {
        conn.Open();

        cmd = conn.CreateCommand();
        cmd.CommandText = "select id from distributor";
        var reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            distributorPasok.Items.Add(reader.GetString("id"));
        }

        conn.Close();
    }

this is my code to show book id

public void loadBukuID()
    {
        conn.Open();

        cmd = conn.CreateCommand();
        cmd.CommandText = "select id from buku";
        var reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            bukuPasok.Items.Add(reader.GetString("id"));
        }

        conn.Close();
    }

this is my code to add qty

public void increaseQty()
    {
        conn.Open();

        cmd = conn.CreateCommand();
        cmd.CommandText = "update buku set stok=stok + @jumlah where id=@id";
        cmd.Parameters.AddWithValue("@jumlah", Convert.ToString(jumlahPasok.Value));
        cmd.Parameters.AddWithValue("@id", bukuPasok.Text);
        cmd.ExecuteNonQuery();

        conn.Close();
    }

this is my code to add the transaction data of the stock addition

try
        {
            if (distributorPasok.Text == "" || bukuPasok.Text == "" || jumlahPasok.Value == 0)
            {
                MessageBox.Show("Data harus terisi dengan valid!");
            } else
            {
                conn.Open();

                cmd = conn.CreateCommand();
                cmd.CommandText = "insert into pasok (id_distributor, id_buku, jumlah, tanggal) values (@distributor, @buku, @jumlah, @tanggal)";
                cmd.Parameters.AddWithValue("@distributor", distributorPasok.Text);
                cmd.Parameters.AddWithValue("@buku", bukuPasok.Text);
                cmd.Parameters.AddWithValue("@jumlah", Convert.ToString(jumlahPasok.Value));
                cmd.Parameters.AddWithValue("@tanggal", Convert.ToDateTime(tanggalPasok.Text));
                cmd.ExecuteNonQuery();

                MessageBox.Show("Pasok telah ditambah!");

                perbaruiPasok();

                conn.Close();
            }
        } catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

and I've called all the classes into the add button.

The connection is already open indicates that the connection is still open when Open() method executed. If you remove all unrelated lines which controls opening & closing connection excluding flow control statements ( if and try...catch block) for related methods, this is what you get:

// Method with try...catch
public void MethodName()
{
    try
    {
        if (...)
        {
            // other stuff
        }
        else
        {
            conn.Open(); // --> opening DB connection

            // other stuff

            conn.Close(); // --> closing DB connection
        }
    }
    catch (Exception ex)
    {
        // exception handling
    }
}

// Other method
public void OtherMethodName()
{
    // opening connection - will trigger exception if conn.Close in MethodName not executed!
    conn.Open(); 

    // other stuff

    conn.Close();
}

When exception occurs between conn.Open() and conn.Close() command, it will go to catch clause but since conn.Close() is not declared there, the connection is still open when second conn.Open() executes.

What you need to fix is placing conn.Close() on finally block which always executed even an exception occurred inside try block:

try
{
    if (...)
    {
        // other stuff
    }
    else
    {
        conn.Open();

        // other stuff
    }
}
catch (Exception ex)
{
    // exception handling
}
finally
{
    // always executed regardless of exception
    if (conn.State == ConnectionState.Open)
        conn.Close();
}

In much better way, it is recommended to use using statements which automatically calls Dispose() method (implicitly calls Close() ) for IDisposable connection objects, see this example:

// declare connection string class-level instead of MySqlConnection
string connectionString = "server=localhost;database=buku;uid=fkrfdllh;pwd=*********"

try 
{
    if (empty_input)
    {
        MessageBox.Show("message text");
    }
    else
    {
        // wrap both MySqlConnection & MySqlCommand on using statements
        using (var conn = new MySqlConnection(connectionString))
        {
            conn.Open();
            using (var cmd = new MySqlCommand("[command_text]", conn))
            {
                cmd.Parameters.AddWithValue("[param_name]", value);

                // other parameters here

                cmd.ExecuteNonQuery();

                MessageBox.Show("[success_message]");

                // other methods
            }

        }
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

Related issue:

Why do I get a "connection is already open" error during a MySQL update statement?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM