0

ユーザーの作成時に、ユーザー テーブルと電子メール テーブルの両方に行を挿入する必要があります。それらのいずれかで失敗する可能性があります(一意の制約)。失敗の原因を特定するにはどうすればよいですか? 私の考えでは、挿入の前にロックを使用してデータベースにクエリを実行したり、返された SqlException を解析したりしていました(これはやりたくない)。

編集:これは複数のマシンで同時に実行されることを言及する必要がありました。異なるデータベースをサポートしたいと思います。

編集 2: 私の解決策は、重複のチェックにロックを使用することになりました。ストアド プロシージャはオプションでしたが、ビジネス ロジックをデータベースに配置したくありませんでした。私は、Web ファームでの競合状態を認識していると他の人にコメントしましたが、状況がまれであるため、これ以上作業する必要はありませんでした。

4

4 に答える 4

2

データベースがダウンしている、またはコマンドがタイムアウトをオーバーランしたなど、主要でないシナリオをキャプチャするには、例外処理を使用する必要があります。ユーザーが一意であり、電子メールが一意であることに制約がある場合は、データを送信する前に実際にテストする必要があります。これらのシナリオを処理する方法としてチェック/インデックス制約に依存することは、長期的には混乱を招くことになります。さらに、エラー処理における重要なベスト プラクティスは、エラーが発生した理由の詳細をエンド ユーザーに知らせないことです。

于 2009-10-01T18:20:32.307 に答える
1

ストアドプロシージャを使用して、トランザクション内でトランザクションが失敗する既知の条件を確認します。例:

BEGIN TRANSACTION
IF EXISTS (SELECT UserID FROM User WHERE UserID = @UserID)
   BEGIN
      ROLLBACK
      SELECT 'User already exists in the User table.'
      RETURN 1
   END

IF EXISTS (SELECT UserID FROM Email WHERE UserID = @UserID)
   BEGIN
      ROLLBACK
      SELECT 'User already exists in the Email table.'
      RETURN 2
   END

INSERT INTO User ...
INSERT INTO Email ...
COMMIT
RETURN 0

これは実際には、エラーを返すために2つのメカニズム(リターンコードと結果セット)を使用しています。通常は1つだけを使用するのが理にかなっています。

于 2009-10-01T18:44:28.357 に答える
0

探しているエラーを提供するためにデータベースだけに頼るのではなく、ビジネスロジックのどこかでそのようなケースをキャッチする必要があります。

于 2009-10-01T18:13:02.610 に答える