3

実行する 2 つの SQL 挿入があります (たとえば、テーブル A と B の場合)。データベースの一貫性を維持したいため、トランザクション内にあります。つまり、A のタプルには B の参照が必要です。

2 番目の挿入では、最初の ID が必要ですが、トランザクションをコミットするまでこの ID は取得できません。
だから私は立ち往生しています。最初の挿入をトランザクションから除外したくありません。最初の挿入は正常に行われますが、2 番目の挿入は正常に行われず、データベースに一貫性のない状態が残ることがあります。

この状況でのベストプラクティスは何ですか?

編集: コードは次のとおりです。

TransactionStatus txStatus = transactionManager.getTransaction(txDefinition);
try{
    Integer aId = insertIntoA();
    insertIntoB(aId);
}catch(){
    transactionManager.rollback(txStatus);
    throw new CustomException(); 
}
transactionManager.commit(txStatus);

指摘したいのは、トランザクションをコミットするまでaIdを取得しないため、B に null を挿入することです。

4

3 に答える 3

2

MySQL では、次のinsertIntoAことができるはずです。

SELECT LAST_INSERT_ID()

...挿入に使用したのと同じ接続で、identity探している列の値であると仮定します。

編集:あなたがそれをやっていて、それがうまくいかない場合(あなたのコメントによると)、私は何が起こっているのかを見るために中間層を見ていきます. MySQLはそれで問題ありません:

mysql> create table A (id int(11) not null auto_increment, descr varchar(64), primary key (id));
Query OK, 0 rows affected (0.13 sec)

mysql> create table B (fk int(11) not null, descr varchar(64));
Query OK, 0 rows affected (0.06 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into A (descr) values ('Testing 1 2 3');
Query OK, 1 row affected (0.00 sec)

mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                1 |
+------------------+
1 row in set (0.03 sec)

mysql> insert into B (fk, descr) values (1, 'Test complete');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from A;
+----+---------------+
| id | descr         |
+----+---------------+
|  1 | Testing 1 2 3 |
+----+---------------+
1 row in set (0.02 sec)

mysql> select * from B;
+----+---------------+
| fk | descr         |
+----+---------------+
|  1 | Test complete |
+----+---------------+
1 row in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into A (descr) values ('Second test');
Query OK, 1 row affected (0.01 sec)

mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

mysql> insert into B (fk, descr) values (2, 'Second test complete');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.08 sec)

mysql> select * from A;
+----+---------------+
| id | descr         |
+----+---------------+
|  1 | Testing 1 2 3 |
|  2 | Second test   |
+----+---------------+
2 rows in set (0.02 sec)

mysql> select * from B;
+----+----------------------+
| fk | descr                |
+----+----------------------+
|  1 | Test complete        |
|  2 | Second test complete |
+----+----------------------+
2 rows in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into A (descr) values ('We''ll roll this one back.');
Query OK, 1 row affected (0.00 sec)

mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                3 |
+------------------+
1 row in set (0.00 sec)

mysql> insert into B (fk, descr) values (3, 'Won''t see this one.');
Query OK, 1 row affected (0.00 sec)

mysql> select * from B;
+----+----------------------+
| fk | descr                |
+----+----------------------+
|  1 | Test complete        |
|  2 | Second test complete |
|  3 | Won't see this one.  |
+----+----------------------+
3 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from A;
+----+---------------+
| id | descr         |
+----+---------------+
|  1 | Testing 1 2 3 |
|  2 | Second test   |
+----+---------------+
2 rows in set (0.00 sec)

mysql> select * from B;
+----+----------------------+
| fk | descr                |
+----+----------------------+
|  1 | Test complete        |
|  2 | Second test complete |
+----+----------------------+
2 rows in set (0.00 sec)
于 2009-10-09T13:42:10.377 に答える
1

あなたはどのIDを見ていますか?トランザクションのステータスに関係なく、シーケンス (一般的なシナリオ) を介して自動生成された主キー ID を (たとえば) 取得できるはずです。明確にするためにいくつかのコードを投稿できますか?

于 2009-10-09T13:33:20.317 に答える
0

最初の挿入の後、できますか

SELECT @@IDENTITY

挿入したばかりの行の ID を取得するには?

于 2009-10-09T13:33:36.370 に答える