C#.net并发问题 - SQL连接然后ADO.net发生变化

时间:2009-09-16 04:43:22

标签: c# ado.net concurrency

我有一个c#.net程序,我需要先使用sql连接将数据插入表中,然后使用ADO.net调整同一组数据。我不确定如何确保在执行ado.net更改之前通过sql连接完成插入。当我尝试下面的代码时,我收到了并发冲突。我猜这是一个竞争条件问题。

我在UpdateAll语句中遇到并发冲突错误,我似乎无法解决它

感谢您的帮助。

下面是一个代码示例,其中SQL和ado.net的更改大大简化了。

  try
  {

   String deleteQuery = "DELETE FROM dbo.TABLENAME";

   String reportQuery = @"

  INSERT INTO TABLENAME 
  (
  COLUMN1, 
  COLUMN2, 
  COLUMN3
  )

  SELECT 
  COLUMN1,
  COLUMN2,
  COLUMN3
  FROM OTHERTABLES

  ";



            SqlConnection ReportConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
            SqlCommand cmd = new SqlCommand();

            cmd.CommandType = CommandType.Text;
            cmd.Connection = ReportConnect;
            cmd.CommandTimeout = Convert.ToInt32(Properties.Settings.Default.ReportTimeout.ToString());


            ReportConnect.Open();

            cmd.CommandText = deleteQuery;

            cmd.ExecuteNonQuery();

            cmd.CommandText = reportQuery;

            cmd.ExecuteNonQuery();

            ReportConnect.Close();

            ReportConnect.Close();

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

        }



        try
        {
            foreach (DataRow dr in DataSet.TABLENAME)
            {
            dr[0] = whatever;
            dr[0] = 100;
            dr[0] = 42.42;
            }
        }
        catch (Exception ax)
        {
            MessageBox.Show(ax.Message);
        }
        finally
        {
            this.tableAdapterManager.UpdateAll(this.DataSet);
        }

2 个答案:

答案 0 :(得分:2)

这里的问题是“tableAdapterManager”似乎是在进行数据更改之前创建并打开的(使用sqlcommand)。如果使用向导创建SqlDataAdapter,则默认情况下并发模式是乐观的(因此update和delete语句会检测数据库是否已更改...)并因您公开的异常而失败。

您可以在向导窗口“生成SQL语句”中解决此问题,单击“高级选项”并取消选中“使用乐观并发”选项。

您也可以从form.designes.cs文件中更改此内容,查找SqlDataAdapter的UpdateCommand,并确保在创建SqlParameter时将DataRowVersion设置为“Default”或使用其他构造函数。

答案 1 :(得分:0)

理论上,在SQL运行之前,ExecuteNonQuery不会完成,这使得你的问题没有实际意义。如果你故意异步执行,那将是另一回事,但你不是。 当然,您仍应注意由多个并发用户引起的问题。