by WebSurfer
2011年12月18日 20:33
Visual Studio を利用してウィザードベースで自動生成する型付 DataSet + TableAdapter を使ってデータベースを更新する際、手動トランザクション処理するにはどうしたらいいでしょうか?(MS-DTC を使う自動トランザクションではなくて)
Visual Studio 2008 から TableAdapter に Transaction プロパティが追加されたので、それと、それ以前からある Connection プロパティを使えば、Visual Studio 2005 以前と比較して手動トランザクションが容易に設定できます。
でも、Visual Studio 2008 以降を使っているなら、そもそも手動トランザクションをかけるコードを自力で書く必要はなくて、自動生成される TableAdapterManager クラスの UpdateAll メソッドを使用すればいいです。
実は知らなかったのですが、TableAdapterManager.UpdateAll メソッドのコードをよく見てみると、そのメソッドの中でトランザクションがかかるようになってました。
もともと、TableAdapterManagerは 階層更新 を実現する
ため(即ち、複数のテーブルを、データベース内の制約によって定義される一貫性規則を守って関連レコードの挿入、更新、および削除を制御するため)のものということらしいですが、単一テーブルの場合もトランザクションは有効に働きます。
という訳で、Visual Studio 2008 以降なら TableAdapterManager の UpdateAll メソッドを使うのが正解だと思います。
ちなみに、Visual Studio 2005 以前の場合は Transaction プロパティは自動生成されたコードには定義されません。TableAdapter は partial クラスとして定義されているので、自動生成されたファイルとは別に、Visual Studio 2008 以降で生成されるコードを参考に、自力で Transaction プロパティを定義して使うのがいいと思います。SqlClient の場合は以下のような感じです。
private System.Data.SqlClient.SqlTransaction _transaction;
internal System.Data.SqlClient.SqlTransaction Transaction {
get {
return this._transaction;
}
set {
this._transaction = value;
for (int i = 0; i < this.CommandCollection.Length; i++) {
this.CommandCollection[i].Transaction = this._transaction;
}
if (((this.Adapter != null)
&& (this.Adapter.DeleteCommand != null))) {
this.Adapter.DeleteCommand.Transaction = this._transaction;
}
if (((this.Adapter != null)
&& (this.Adapter.InsertCommand != null))) {
this.Adapter.InsertCommand.Transaction = this._transaction;
}
if (((this.Adapter != null)
&& (this.Adapter.UpdateCommand != null))) {
this.Adapter.UpdateCommand.Transaction = this._transaction;
}
}
}
どうも、Visual Studio 2008 から TableAdapter に Transaction プロパティが追加された理由は、TableAdapterManager.UpdateAll メソッドで手動トランザクションをかけるためのようです。