C# トランザクション管理 データの更新

今回は、トランザクションを利用した、データの更新についてまとめていきます。

トランザクションとは、データの更新や削除をした時に、途中でエラーが発生し、中途半端なデータが出来上がるのを阻止するために使います。

トランザクション内に処理を書くことで、エラーが発生したときなど、更新処理をする前のデータに戻すことができるのです。

なのでトランザクションは、セーブポイントというイメージで私は使用しています。

とても便利なので是非使い方をマスターしてください!それではやっていきましょう。

ちなみに、SQLServerへの接続の方法がそもそもわからない方は、先にこちらの記事を参考にしてみてください。

トランザクションの使い方

トランザクションを開始するには、SqlConnection.BeginTransaction()を使用します。

SqlTransaction 変数= SqlConnection型.BeginTransaction();

これで、トランザクションが開始されました。

次にトランザクションを終了する時ですが、正常に処理が行われたときは「Commit」、エラーが発生した場合は、「Rollback」を行います。

「Commit」は、トランザクションを開始してから、更新したデータを確定させることができます。

「Rollback」は、トランザクションを開始した状態に、データを戻すことができます。

//正常終了(コミット)
tran.Commit();
//異常終了(ロールバック)
tran.Rollback();

 

データの更新

早速例を見てみましょう。
下記のようなデータを用意したので、データを更新していきます。

SELECT * FROM hironimoTable
id   |nickName|animal|height|weight|insDt                  |updDt
-----+--------+------+------+------+-----------------------+-----------------------
00001|ひろにも|きりん|150   |55.5  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00002|ひろにも|きりん|160   |60.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00003|ひろにも|きりん|170   |70.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00004|ひろにも|きりん|180   |80.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00005|ひろにも|きりん|150   |90.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000

 

データの更新を行うには、SqlCommand.ExecuteNonQuery()を利用しましょう。更新件数を取得することもできます。

int 更新件数 = SqlCommand.ExecuteNonQuery();

正常時(Commit)

id:00001のheightを150から170に変更し、更新していきます。

try
{
    //SQLServerの接続開始
    SqlConnection sqlconn = new SqlConnection(Properties.Settings.Default.sqlServer);
    sqlconn.Open();

    //トランザクション開始
    SqlTransaction tran = sqlconn.BeginTransaction();

    try
    {
        //SQL作成
        StringBuilder sql = new StringBuilder();
        sql.AppendLine("UPDATE hironimoTable");
        sql.AppendLine("SET");
        sql.AppendLine("  height = 170");
        sql.AppendLine("WHERE");
        sql.AppendLine("  id = '00001'");

        //SQL実行
        SqlCommand command = new SqlCommand(sql.ToString(), sqlconn, tran);
        int result = command.ExecuteNonQuery();

        tran.Commit();
        MessageBox.Show("更新件数:" + result.ToString() + "件");

    }
    catch 
    {
        tran.Rollback();
        throw;
    }                

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

解説
22行目:SqlCommand.ExecuteNonQuery();でデータの更新を行っています。
返却値は更新した件数を返しますので、今回はresultに1が格納されます。

24行目:正常の場合は、SqlTransaction.Commit();でデータが確定されます。

結果を見てみましょう。

SELECT * FROM hironimoTable
id   |nickName|animal|height|weight|insDt                  |updDt
-----+--------+------+------+------+-----------------------+-----------------------
00001|ひろにも|きりん|170   |55.5  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00002|ひろにも|きりん|160   |60.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00003|ひろにも|きりん|170   |70.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00004|ひろにも|きりん|180   |80.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00005|ひろにも|きりん|150   |90.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000

id:00001のデータが更新されていました。

異常時(Rollback)

id:00001のheightを170→180→AAAに変更し、更新していきます。
この時、heightは数値しか入らないのでエラーが発生します。

try
{
    //SQLServerの接続開始
    SqlConnection sqlconn = new SqlConnection(Properties.Settings.Default.sqlServer);
    sqlconn.Open();

    //トランザクション開始
    SqlTransaction tran = sqlconn.BeginTransaction();

    try
    {
        //SQL作成
        StringBuilder sql = new StringBuilder();
        sql.AppendLine("UPDATE hironimoTable");
        sql.AppendLine("SET");
        sql.AppendLine("  height = 180");
        sql.AppendLine("WHERE");
        sql.AppendLine("  id = '00001'");

        //SQL実行
        SqlCommand command = new SqlCommand(sql.ToString(), sqlconn, tran);
        int result = command.ExecuteNonQuery();

        //SQL作成
        sql = new StringBuilder();
        sql.AppendLine("UPDATE hironimoTable");
        sql.AppendLine("SET");
        sql.AppendLine("  height = 'AAA'");
        sql.AppendLine("WHERE");
        sql.AppendLine("  id = '00001'");

        //SQL実行
        command = new SqlCommand(sql.ToString(), sqlconn, tran);
        result = command.ExecuteNonQuery();

        tran.Commit();
        MessageBox.Show("更新件数:" + result.ToString() + "件");

    }
    catch 
    {
        tran.Rollback();
        throw;
    }                

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

解説
33行目:SqlCommand.ExecuteNonQuery();でデータの更新を行っていますが、エラーが発生し、42行目のcatchに処理が行き、Rollback()されます。

SELECT * FROM hironimoTable
id   |nickName|animal|height|weight|insDt                  |updDt
-----+--------+------+------+------+-----------------------+-----------------------
00001|ひろにも|きりん|170   |55.5  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00002|ひろにも|きりん|160   |60.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00003|ひろにも|きりん|170   |70.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00004|ひろにも|きりん|180   |80.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000
00005|ひろにも|きりん|150   |90.0  |2020-03-02 00:00:00.000|2020-03-02 00:00:00.000

データも更新されていません。

この時トランザクションを開始せずにこの処理を行うと、id:00001の身長は更新されたまま(180)になりますが、

トランザクションを開始しているため、更新されず元の値(170)になっています。

システムエラーが発生したときに、変なデータを残したくないので必ず更新処理の時はトランザクションを開始するようにしましょう!

 

まとめ

今回は、トランザクションとデータの更新について記載しましたが、とても大切なので是非理解していきましょう。
特にトランザクションについては、セーブポイントというイメージを持って、データ更新の際は忘れずに実装してほしいと思います。

今日のポイント
  • トランザクションは、セーブポイントみたいなイメージ
  • トランザクションの開始:SqlConnection.BeginTransaction()
  • トランザクションの終了:正常時はCommit() 異常時はRollback()
  • データ更新は、SqlCommand.ExecuteNonQuery()

 

C#の記事一覧

おすすめの記事