1

次の表を考えます。

create table permissions(id identity);
create table companies(id identity, 
    permission_id bigint not null, 
    foreign key(permission_id) references permissions(id) on delete cascade);
create table departments(id identity, 
    company_id bigint not null, 
    permission_id bigint not null, 
    foreign key(company_id) references companies(id), 
    foreign key(permission_id) references permissions(id) on delete cascade);

部門が削除されたら、次のステートメントをアトミックに実行したいと考えています。

  • departments行が削除されます
  • permissions部門行に関連付けられた行が削除されます
  • companies部門行に関連付けられた行が削除されます
  • permissions会社 (前のポイント) に関連付けられた行が削除されます

質問:

  1. すべての外部キーに対してREAD_COMMITTEDトランザクション分離を使用すると、行は単一のアトミック ステートメントとして削除されますか? それとも、異常ON CASCADE DELETEに対して脆弱な個別の削除ステートメントとして実行されますか?READ_COMMITTED
  2. 会社/部門が削除されたときに (可能であれば原子的に) 会社/部門のアクセス許可を削除するようにデータベースに指示するにはどうすればよいですか?
  3. SQL標準はこの質問について何か言っていますか? それとも、異なるデータベース間で動作が異なりますか?

説明:

  1. 会社/部門は権限テーブルを参照する必要があり、その逆ではありません。これは、クロージャー テーブルpermissionsを形成するためです(たとえば、ユーザーは会社に対して権限を持ち、会社は部門に対して権限を持っているため、ユーザーは部門に対して権限を持ちます)。階層関係はさまざまなタイプ (つまり、ユーザー、会社、部門) にまたがるため、権限テーブルは特定のタイプを指すことはできません。したがって、会社/部門は許可を参照する必要があり、その逆ではありません。
  2. CASCADE部門を削除したいとします。部門の許可、部門、および会社は削除されますが、会社の許可は削除されないため、許可を削除して残りを処理するだけでは十分ではありません。
  3. H2 はメイン ステートメントとは別のデータベース接続でトリガーを実行し、2 つのステートメントが同じ会社/部門の行で書き込みロックを要求するため、会社/部門が削除された後にトリガーを使用して権限を削除することはできません。companies最初の接続は、削除している行をロックします。permissions2 番目の接続 (トリガー)は、会社に関連付けられた行を削除しようとON CASCADE DELETEしますが、会社もロックする必要があります。これは、回避策がある H2 の制限が原因でした。https://groups.google.com/d/msg/h2-database/B3xG488RBhI/DOsIMVmPBnAJを参照
4

1 に答える 1