C#を使用してデータベースにレコードを挿入するときにトランザクションを使用する

c# sql sql-server transactions tsql
C#を使用してデータベースにレコードを挿入するときにトランザクションを使用する

私はSQLトランザクションを使用したことがないので、私の場合は本当にトランザクションを使用する必要があることを知っています。 私のアプリの機能の1つは、Excelファイルをデータベースに変換することです。

そのため、Excelから値を取得し、引数(SPに送信される)とメインテーブルに直接挿入する値と、セカンダリテーブルに挿入する値を含む文字列の配列を作成します。メインテーブルのこれらの値の代わりにIDを取得します。 私が言っているのは、私は外部キーを持っているということです、そしてそれが私がこれをする理由です。

だから私はこれを完璧にやっているが、取引はしていないと思う。 しかし、テーブルに値を挿入するときに何か問題が発生した場合、ロールバックを実行する必要があります。

そのため、このプロセスでは、テーブルごとに1つずつ、5つのストアドプロシージャを使用しています。 これらのSPは、このプロセス専用ではありません。 これらは、レコードを挿入するためにアプリで使用されます。

しかし、私はトランザクションを使用する場所で助けが必要です。 C#(アプリ側)またはSQL Server(サーバー側)で行う必要がありますか?

今のところ、私はC#のSqlTransactionオブジェクトを使用していますが、何らかの方法で動作します。ロールバックを行うと、彼は本当にすべての挿入をキャンセルしますが、トランザクションで使用したIDはもう利用できません。 すべてのテーブルを削除して再度作成した場合にのみ、それらのIDが再び使用可能になります。

だから、私はトランザクションをうまく使用していないと思うので、トランザクションを使用する方法と場所を知るために助けが必要です。

  1  2


ベストアンサー

トランザクションの使用方法については正しい方向に進んでいると思いますが、問題はIDENTITY列のシードがロールバックされないことです。

MS SQL Serverを使用していると思いますか? テーブルを再作成せずにIDENTITY列をリセットするには、DBCC CHECKIDENTを使用できます。

DBCC CHECKIDENT (table_name, RESEED, 99);

これによりシードがリセットされ、次に割り当てられるID値が100になります。 もちろん、BEGIN TRANSACTIONの前にテーブルの最高のID値を記録する必要があります。

これは、単一のライタープロセスがある場合にのみ使用します。 複数のライターの状況では、最初に何らかの深刻なテーブルロックを行わない限り、物事がうまくいく可能性があります。 複数のライターの場合、ID列の値の「穴」が許容されるように、コードの残りの部分を書く方がはるかに良いと思います。

3


Identityカラムを他の目的に使用しておらず、シーケンシャルであることを絶対に必要としない場合、「欠損」値があるという考えに慣れるようにしてください。 各レコードに安価な一意のキーを提供する方法を提供するだけなので、実際には欠落していません。 レコードも削除されるとギャップが発生するため、レコードカウンターとして[ID]列にも依存しないでください。

テーブルを見るときに連番を見るのはいいことですが、コストは自分自身とデータベースエンジンにとって余分な作業です。 それを受け入れるのに何ヶ月もかかりました。

値が再利用されない理由は、その列が外部キーとして使用されるときにデータベースの整合性を提供するためです。

0


タイトルとURLをコピーしました