How can more than one user Insert data to the SQL database at the same time without mix the data on the database.

Well I develop an application under the asp and C#. The idea of this application is to multiple users log in to the app and inserts data to the SQL database server 2008 sp2 at the same time. An user create a subject and then inserting description about this subject , a single user can insert any description data without any problem but when more than one users inserting data then the data does not saved or the data mixed on the databases. For Example if user one inserting for the Subject 1 the data: User1 User1.1 and User two inserting for the Subject 2 the data: User2 User2.1 then the user’s one data saved on the subject of users2. Note that the databases are on Multiuser Mode.... Could you please help me with this problem with examples? Thank you in advanced …

        This Is My C# Code : 
  public void dataInsert()
{
    try
    {
        SqlConnection con = new System.Data.SqlClient.SqlConnection();
        con.ConnectionString = ConfigurationManager.ConnectionStrings["beta"].ConnectionString;
        // storeMulti();

        for (int i = 0; i < howManyFields(); i++)
        {

            TextBox txt = Theat.FindControl("TextBox" + (i + 1)) as TextBox;
            HtmlTableCell cell = Theat.FindControl("Td" + (i + 1)) as HtmlTableCell;
            CheckBox cb = Theat.FindControl("CheckBox" + (i + 1)) as CheckBox;

            TextBox tTitle = Theat.FindControl("tbTitle" + i) as TextBox;
            TextBox tDscr = Theat.FindControl("tbDscr" + i) as TextBox;
            DropDownList dConf = Theat.FindControl("ddConf" + i) as DropDownList;
            DropDownList dType = Theat.FindControl("ddType" + i) as DropDownList;
            HtmlInputFile inFile = Theat.FindControl("tbFile" + i) as HtmlInputFile;

            if (txt.Text.Trim().ToString() != string.Empty)
            {
                //ShowMessageBox("Updated");
                DataSet dsPres = findPresDatasetByLang(Convert.ToInt32(Application["langID"]));
                for (int z = 0; z < dsPres.Tables[0].Rows.Count; z++)
                {
                    System.Data.SqlClient.SqlCommand cmd;
                    cmd = new System.Data.SqlClient.SqlCommand();
                    cmd.Connection = con;                       
                    cmd.CommandText = "INSERT INTO [I_SUBJECT_FIELD] VALUES (@p1,@p2,@p3,@p4,@p5)";

                    cmd.Parameters.AddWithValue("@p1", Convert.ToInt32(Application["subID"].ToString()));
                    cmd.Parameters.AddWithValue("@p2", Convert.ToInt32(dsPres.Tables[0].Rows[z]["ID"].ToString()));
                    cmd.Parameters.AddWithValue("@p3", Convert.ToInt32(Application["langID"].ToString()));
                    cmd.Parameters.AddWithValue("@p4", findFieldTypeID(cell.InnerHtml));
                    cmd.Parameters.AddWithValue("@p5", txt.Text);


                    cmd.Connection.Open();
                    int rowsAffected = cmd.ExecuteNonQuery();
                    cmd.Connection.Close();
                }
            }
               txt.Text = string.Empty;
               cb.Checked = false;
        }
    }

    catch (SqlException sql)
    {
        ShowMessageBox(sql.Message);
    }
    catch (Exception exe)
    {
        ShowMessageBox(exe.Message);
    }
}

Upvotes: 0

Views: 1965

Answers (1)

David
David

Reputation: 218867

Look at where you're getting parameter values for the query:

cmd.Parameters.AddWithValue("@p1", Convert.ToInt32(Application["subID"].ToString()));
cmd.Parameters.AddWithValue("@p3", Convert.ToInt32(Application["langID"].ToString()));

You're getting them from the Application value collection. This is not thread safe. All concurrent users of the application share the same Application value collection. So when one user updates a value in that collection, other users will use that value.

The values being inserted to the database should be supplied to this function, not referenced in the global Application collection. So the function signature might look more like this:

public void dataInsert(int subjectId, int languageId)
{
    // implementation
}

And the query parameters would come from those values:

cmd.Parameters.AddWithValue("@p1", subjectId);
cmd.Parameters.AddWithValue("@p3", languageId);

That way whenever a user invokes this functionality, the code invoking it would simply provide those values instead of storing them in a global collection.

In general, avoid global values. Especially in multi-threaded applications with multiple concurrent users.

Upvotes: 2

Related Questions