1

我主要只是好奇我的方法是否正确。我要做的是循环两个数组并将索引处的值插入到我的数据库中,如果出现故障则回滚。

我在想什么看起来像这样。

        SqlCommand cmd = new SqlCommand();
        SqlConnection cn = new SqlConnection(s.ConnectionString.ConnectionString);

        cmd.Connection = cn;
        cmd.CommandText = "asp_FinalInspectionTransaction";
        cmd.CommandType = CommandType.StoredProcedure;

        SqlTransaction trans = cn.BeginTransaction();
        cmd.Transaction = trans;

        cn.Open();

        try
        {
            for (int i = 0; i < array1.Length - 1; i++)
            {
                cmd.Parameters.AddWithValue("@MasterID", masterID);
                cmd.Parameters.AddWithValue("@TagName", array1[i]);
                cmd.Parameters.AddWithValue("@TagValue", array2[i]);

                cmd.ExecuteNonQuery();

                cmd.Parameters = new SqlParameterCollection();
            }

            trans.Commit();
        }
        catch (SqlException e)
        {
            LogManager lm = new LogManager();
            lm.WriteErrorTextLog(e, "Broken Manager - Final Inspection Broker");
            lm.Dispose();

            trans.Rollback();
        }
        catch (Exception e)
        {
            LogManager lm = new LogManager();
            lm.WriteErrorTextLog(e, "Broken Manager - Final Inspection Broker");
            lm.Dispose();

            trans.Rollback();
        }
        finally
        {
            cn.Close();
        }

我仍在学习 ADO.Net 的所有内容,并且没有使用 SQL 存储过程之外的事务。我知道我可以将它放入 XML 并在它自己的存储过程中执行所有循环和插入。只是好奇这条路线是否也能奏效。任何建议将不胜感激。

4

2 回答 2

4

您也可以尝试将其放入事务范围(http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

using (TransactionScope scope = new TransactionScope())
{
    // your ado.net sql here

    // if success then:
    scope.Complete();
}

这样做的好处是它还会回滚多个 SQL 命令。

于 2012-11-19T20:41:39.160 回答
0

您的建议对我来说看起来不错,唯一的期望是您应该使用更多的关键字using(也添加了一些小修复):

using (SqlCommand cmd = new SqlCommand())
{
    using (SqlConnection cn = new SqlConnection(s.ConnectionString.ConnectionString))
    {
        cmd.Connection = cn;
        cmd.CommandText = "asp_FinalInspectionTransaction";
        cmd.CommandType = CommandType.StoredProcedure;

        SqlTransaction trans = cn.BeginTransaction();
        cmd.Transaction = trans;

        cn.Open();

        try
        {
            for (int i = 0; i < array1.Length - 1; i++)
            {
                cmd.Parameters.AddWithValue("@MasterID", masterID);
                cmd.Parameters.AddWithValue("@TagName", array1[i]);
                cmd.Parameters.AddWithValue("@TagValue", array2[i]);

                cmd.ExecuteNonQuery();

                // cmd.Parameters = new SqlParameterCollection(); <-- This is a read only collection created when constructing the command
            }

            trans.Commit();
        }
        catch (Exception e) // As you are doing the same thing on boths exceptions one handler is enought
        {
            using (LogManager lm = new LogManager())
            {
                lm.WriteErrorTextLog(e, "Broken Manager - Final Inspection Broker");
            }
            trans.Rollback();
        }
    }
}
于 2012-11-19T20:38:27.210 回答