繁体   English   中英

如何在C#.net中使用事务

[英]How to use transaction in C#.net

我想以很高的速度将数据插入sqlserver。 因此,我在c#.net中使用事务,但是在使用事务之后,我注意到插入速度与不使用它没有区别。 请检查我的代码并帮助我解决它。

代码:

void ReadToTable()
    {

        try
        {
            if (dir != "")
            {
                dic.Clear();
                string[] lines = System.IO.File.ReadAllLines(dir);
                foreach (string line in lines)
                {
                    SqlConnection sqlconn = new SqlConnection(DBsetting.Connstring);
                    sqlconn.Open();
                    SqlTransaction transaction = sqlconn.BeginTransaction();
                    if (!string.IsNullOrEmpty(line))
                    {
                        l = line.Split('\t');
                        l[0] = l[0].Trim();
                        l[1] = l[1].Trim();
                        l[2] = l[2].Trim();
                        l[3] = l[3].Trim();
                        if (!string.IsNullOrEmpty(l[0]) && l[3] == "1" || l[3] == "0")
                        {
                            dic.Add(new KeyValuePair<string, string>(l[0], l[1]));
                            PersianCalendar persCal = new PersianCalendar();
                            SqlCommand sqlda = new SqlCommand("insert into readd(IDp,date,day,nobatkari)values(@IDp,@date,@day,@nobatkari)", sqlconn, transaction);
                            sqlda.Transaction = transaction;
                            sqlda.Parameters.AddWithValue("@date", l[1]);
                            sqlda.Parameters.AddWithValue("@IDp", l[0]);
                            sqlda.Parameters.AddWithValue("@day", GetDayOfWeek(GetPerDate(l[1])));
                            sqlda.Parameters.AddWithValue("@nobatkari", "");//ntkari[idx].ToString());
                            sqlda.ExecuteNonQuery();
                            transaction.Commit();
                            sqlconn.Close();
                            sqlconn.Dispose();

                        }
                        else
                        {
                            ReadDataAndInsertIntoTable(line);
                        }
                    }

                }
                RefGrid();
                foreach (var pair in dic)
                {
                    InsertNobatKari(pair.Key, GetPerDate(pair.Value).ToString());
                }
            }

        }
        catch (Exception ex)
        {
            if (ex.Message.Contains("there is no row at position 0"))
            {
                MessageBox.Show("لطفا سطر خالی را انتخاب ننمایید");
            }
            else if (ex.Message.Contains("Cannot insert duplicate key row in object"))
            {
                MessageBox.Show("امکان ورود سطر تکراری وجود ندارد");
            }
            else
            {
                MessageBox.Show(ex.Message);
            }
        }
        finally
        {

        }
    }

我想以很高的速度将数据插入sqlserver。因此我在c#.net中使用事务,但是在使用事务后,我注意到插入速度与不使用它没有区别。

是的,您不会看到改善,因为交易不是为了提高速度。 另外,您没有正确使用事务:您没有提交事务。


您的方法

想想你在做什么。 您正在循环一个文件中的行,并为每一行创建一个数据库连接,然后一直到数据库插入一条记录。 您执行n次,其中n是您的文本文件中的记录数。

另一件事是您正在使用File.ReadAllLines ,它将把整个文件读入内存:如果文件真的很大怎么办? 你的记忆能应付吗?


更好的方法

更好的方法是创建一个连接,然后转到数据库并获取一批记录(50、100或更多),然后一次完成。 继续执行此操作,直到所有记录都输入为止。

另外,您应该使用File.ReadLines以便它会延迟读取每一行(一旦被请求,它将把该行加载到内存中)。

要提高速度,请使用SqlBulkCopy 确保您阅读了有关列映射的部分。

脚步:

  1. 从文件中读取一行。
  2. 在这一行的基础上,创建您的内存表结构。

     string[] strArray = line.Split('\\t'); var dt = new DataTable(); for (int index = 0; index < strArray.Length; index++) dt.Columns.Add(new DataColumn()); 
  3. 从文件填充内存数据表:

     do { DataRow row = dt.NewRow(); string[] itemArray = line.Split('\\t'); row.ItemArray = itemArray; dt.Rows.Add(row); i = i + 1; line = sr.ReadLine(); } while (!string.IsNullOrEmpty(line)); 
  4. 将数据发送到数据库:

     var bc = new SqlBulkCopy(dbConn, SqlBulkCopyOptions.TableLock, null) { DestinationTableName = "TestData", BatchSize = dt.Rows.Count }; dbConn.Open(); bc.WriteToServer(dt); dbConn.Close(); bc.Close(); 

如果文件很大,则可以分批执行步骤4。 在上面的代码中, sr变量将是StreamReader一个实例,但是无论如何您都可以使用它来读取文件。


注意:

此代码不可复制粘贴,而只是作为指导,因此您需要对其进行调整以适合您的需求。

您为插入的每行创建一个事务,这与不进行事务的所有操作几乎相同。 您可能应该执行以下操作:

    string[] lines = System.IO.File.ReadAllLines(dir);
    SqlConnection sqlconn = new SqlConnection(DBsetting.Connstring);
    sqlconn.Open();
    SqlTransaction transaction = sqlconn.BeginTransaction();
    foreach (string line in lines)
    {
        ...
    }
    transaction.Commit();
    sqlconn.Close();
    sqlconn.Dispose();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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