それはそのようには機能しません。検討してください:
- プログラム1では、トランザクションを開き、autoinc主キーを持つテーブルFOOに挿入します(任意に、キー値として557を取得すると言います)。
- プログラム2が開始し、トランザクションを開き、テーブルFOOに挿入して558を取得します。
- FOOへの外部キーである列を持つテーブルBARに2つの挿入をプログラムします。したがって、558はFOOとBARの両方に配置されています。
- プログラム2がコミットするようになりました。
- プログラム3が開始され、テーブルFOOからレポートが生成されます。 558レコードが印刷されます。
- その後、プログラム1がロールバックします。
データベースはどのようにして557値を再利用しますか?それはFOOに入り、557より大きい他のすべての主キーをデクリメントしますか? BARをどのように修正しますか?レポートプログラム3の出力に印刷された558をどのように消去しますか?
Oracleのシーケンス番号も、同じ理由でトランザクションに依存しません。
この問題を一定時間で解決できれば、データベース分野で大金を稼ぐことができると確信しています。
ここで、自動増分フィールドにギャップがないという要件がある場合(たとえば、監査目的で)。その後、トランザクションをロールバックすることはできません。代わりに、レコードにステータスフラグを設定する必要があります。最初の挿入では、レコードのステータスは「未完了」です。次に、トランザクションを開始し、作業を実行して、ステータスを「競合」(または必要なもの)に更新します。次にコミットすると、レコードがライブになります。トランザクションがロールバックした場合でも、監査のために不完全なレコードが残っています。これは他の多くの頭痛の種を引き起こしますが、監査証跡に対処する1つの方法です。