今回の記事はC#を用いてSQLサーバーにSQLクエリを投げる途中でエラーが起きた際、そのリカバリーで非常に有用なトランザクションの使用方法に関してご紹介します。初心者にもわかるようにトランザクションを使う有用性からご紹介しますので、是非参考にしてください。
ではメインの記事に進みましょう。
SQLにおけるトランザクションとは?
SQLにおけるトランザクションとはSQLの実行時エラーが起きた際に、非常に有用になるエラー対策です。
例えばSQLクエリでクライアント側となるクエリ送信者と、サーバ側になるクエリ実行端末が分かれている一般的な例のATMを例に考えてみます。
クエリの流れとしては下記のような流れです。
仮定(SQLデータベースには10000円分と記載してある)
①クライアント操作者がATMに1000円引き出す指令を出す
②クライアントからサーバに1000円引き出すためのクエリ発行
クエリの内容はサーバのデータベースに登録している10000円から1000円を引いた、9000円にデータを変更するUPDATE文が行われます。
③サーバでクエリ実行と実行完了
④サーバ側でデータ変更完了
この時点でデータベースには9000円になっている
⑤ATMでエラー発生お金が引き出せない
このATMでお金が引き出せないという現象が起きたとします。
この場合、操作者のデータ(銀行残高)はお金を受け取っていないのに9000円に減ってしまい痛手を被っています。
こういった流れを防ぐためにトランザクションがあります。
トランザクションを使用することで、下記のような操作が可能になります。
仮定(SQLデータベースには10000円分と記載してある)
①クライアント操作者がATMに1000円引き出す指令を出す
トランザクションを開始
②クライアントからサーバに1000円引き出すためのクエリ発行
クエリの内容はサーバのデータベースに登録している10000円から1000円を引いた、9000円にデータを変更するUPDATE文が行われます。
③サーバでクエリ実行と実行完了
④サーバ側でデータ変更完了
この時点でデータベースには9000円になっている
⑤
[正常動作]
トランザクションをcommitして操作終了
ATMからお金が発行
[エラー動作]
トランザクション開始時に処理を戻す(Rollback)
これでもしもエラーが起きた際でも、何もなかったように処理を戻すことが可能になります。トランザクションの開始タイミングは注意する必要はありますがとても便利な機能です。
では実際に使用する方法をご紹介していきます。
C#でデータベースを操作する方法
C#でデータベース操作に慣れていない方は一通りの操作例を記載しているので下記記事を3個にしてみてください。
「【C#】SQLサーバーでデータを追加・更新・削除・取得する方法。」
各リンクからご参照ください。
C#でトランザクションを使う方法
ではトランザクションを使用する方法に関してご紹介していきます。
using System;
using System.Data.SqlClient;
namespace CSharpSQLServerTransaction
{
class Program
{
// データベース接続文字列
private static readonly string ConnectionString = "Data Source=<ホスト名、またはIPアドレス>; Initial Catalog=SampleDB; User Id=SampleUser; Password=SamplePassword;";
// データ更新のSQL
private static readonly string UpdateSql = "UPDATE person SET name=@name WHERE id=@id";
static void Main(string[] args)
{
try
{
// コネクションを生成します。
using (var connection = new SqlConnection(ConnectionString))
// コマンドオブジェクトを作成します。
using (var command = connection.CreateCommand())
{
SqlTransaction transaction = null;
try
{
// コネクションをオープンします。
connection.Open();
// トランザクションを開始します。
transaction = connection.BeginTransaction();
// データ更新のSQLを実行します。
command.CommandText = UpdateSql;
command.Parameters.Add(new SqlParameter("@name", "jiro"));
command.Parameters.Add(new SqlParameter("@id", 2));
var result = command.ExecuteNonQuery();
//「#ここまでがクエリ実行」
// 実行された結果が1行ではない場合
if (result != 1)
{
Console.WriteLine("データを更新できませんでした。");
// ロールバックします。
transaction.Rollback();
return;
}
// コミットします。
transaction.Commit();
}
// データベース操作で例外が発生した場合
catch (Exception e)
{
// 例外の内容を表示します。
Console.WriteLine(e.Message);
// トランザクションが有効な場合
if (transaction != null)
{
// ロールバックします。
transaction.Rollback();
}
}
}
}
// コネクションオブジェクト、コマンドオブジェクトの生成で例外が発生した場合
catch (Exception e)
{
// 例外の内容を表示します。
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
}
}
上記コードはネットからの引用ですが、簡単に解説しておきます。データベース接続後、コマンドの置き換えを行い、その後クエリ実行を行っています。(「#ここまでがクエリ実行」まで)
このクエリを実行した後、実行後の結果が1つではないというエラーが発生した場合にトランザクション開始位置にロールバックするという仕組みになっております。
また、データベースでのエラーに関してもtry文で拾い、ロールバックしています。
データベース接続後にトランザクションを開始、仮にデータテーブルにデータを入れるのであればコミットの後に入れるがポイントです。
コミット前にデータテーブルに取得してきたデータを入れるとエラーになりますのでご注意を。
では、今回の記事は以上です。他にも多数のC#関連の記事を記載しているので是非参考にしていた抱けると幸いです。
コメント