TransactionScope似乎无法正常工作

时间:2016-03-25 18:49:22

标签: c# sql-server ado.net

我正在努力确保下面的插入和删除工作完全或根本不工作。我在我的交易范围之外有我的连接对象,我认为这是正确的,不是100%肯定。

我知道这段代码不符合我的意图。在第一部分(插入运行)之后然后我通过终止在断点上中止,即使我从未调用scope.complete,也确实插入了行。

请在这里指出我的想法和逻辑中的缺陷。

                sqlConnection.Open();

                int numFound = 1;
                int max = 99;
                int iteration = 0;
                while (iteration < max && numFound > 0)
                {
                    iteration++;
                    var ids = new List<int>();
                    using (var sqlCommand0 = new SqlCommand(sql0, sqlConnection))
                    {
                        using (SqlDataReader reader1 = sqlCommand0.ExecuteReader())
                        {
                            while (reader1.Read())
                            {
                                ids.Add(reader1.GetInt32(0));
                            }
                        }
                    }
                    numFound = ids.Count;
                    if (numFound > 0)
                    {
                        using (var scope = new TransactionScope())
                        {
                            string whereClause = $"WHERE Id IN ({string.Join(",", ids)})";

                            string sql1 = string.Format(sqlTemplate1, whereClause);
                            using (var sqlCommand1 = new SqlCommand(sql1, sqlConnection))
                            {
                                sqlCommand1.ExecuteNonQuery();
                            }

                            // BREAK POINT HERE - ABORTED PROGRAM AND sql1 had been committed.

                            var sql2 = "DELETE FROM SendGridEventRaw " + whereClause;
                            using (var sqlCommand2 = new SqlCommand(sql2, sqlConnection))
                            {
                                sqlCommand2.ExecuteNonQuery();
                            }
                            scope.Complete();
                            total += numFound;
                            Console.WriteLine("deleted: " + whereClause);
                        }
                    }
                }
            }

2 个答案:

答案 0 :(得分:3)

我认为这是因为您在开始交易之前打开了连接。您可以尝试通过先启动交易然后打开连接来解决问题。

答案 1 :(得分:0)

仅仅从我所看到的和我所假设的是你打算发生的是这个: 如果您的第一个查询获得了一些记录,则执行下一个查询,因此语句为:

if (numFound > 0)

如果是这种情况,并且断点的位置为true,则插入语句当然会触发。原因是:

 using (var sqlCommand1 = new SqlCommand(sql1, sqlConnection))
                            {
                                sqlCommand1.ExecuteNonQuery();
                            }

在if语句中。您说“如果有任何行,请执行插入查询。”

如果您尝试实际获取scope对象来执行查询,那么您将不得不在对象内进行所有查询构建,然后让scope.complete()进行执行。

例如:

//In TransactionScope class

public string Complete(var ids, int numFound, SqlConnection sqlConnection, string sqlTemplate1)
{
    string whereClause = $"WHERE Id IN ({string.Join(",", ids)})";

                            string sql1 = string.Format(sqlTemplate1, whereClause);
                            using (var sqlCommand1 = new SqlCommand(sql1, sqlConnection))
                            {
                                sqlCommand1.ExecuteNonQuery();
                            }

                            var sql2 = "DELETE FROM SendGridEventRaw " + whereClause;
                            using (var sqlCommand2 = new SqlCommand(sql2, sqlConnection))
                            {
                                sqlCommand2.ExecuteNonQuery();
                            }
                            return whereClause;
}


//in your Main class

if (num > 0)
{
    string whereClause = scope.Complete(ids, numFound, sqlConnection, sqlTemplate1);
    Console.WriteLine("deleted" + whereClause"." );
}

我当然只是偏离了上面提到的假设。如果我不对,请告诉我。

希望它有所帮助。