1

これに対する私のアプローチが正しいかどうか、主に興味があります。私がやろうとしているのは、2 つの配列をループして、データベースのインデックスに値を挿入し、何かが失敗した場合はロールバックすることです。

私が考えていることは、このようなものになります。

        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 に答える