事务有两个sql插入

发布于 2024-08-07 03:41:39 字数 580 浏览 6 评论 0原文

我有两个sql插入要做(例如表A和B中的例子),它们在一个事务中,因为我希望数据库保持一致,也就是说,A中的元组必须在B中具有引用。

在第二个插入中我需要来自第一个的 id,但在提交事务之前我没有得到这个 id。
所以我被困住了。我不想从事务中取出第一个插入,可能会发生第一个插入正常但第二个插入不正常的情况,从而使数据库中的状态不一致。

在这种情况下最佳实践是什么?

编辑:这是代码:

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

我想指出的是,在提交事务之前我不会得到aId,因此将 null 插入 B 中。

I have two sql insert to do (say for examples in tables A and B), they are in a transaction because I want the database to remain consistent, that is, a tuple in A must have references in B.

In the second insert I need the id that comes from the first, but I don't get this id until I make a commit on the transaction.
So I'm stuck. I don't want to take the first insert out of the transaction, it may happen that the first insert goes ok but the second does not, leaving me with an inconsistent state in the database.

What is best practice in this situation?

EDIT: Here is the code:

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

What I want to point out is that I do not get aId until I commit the transaction, therefore inserting null into B.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

私野 2024-08-14 03:41:39

在 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)

On MySQL, in insertIntoA you should be able to do:

SELECT LAST_INSERT_ID()

...on the same connection you used for the insert, assuming it's an identity column value you're looking for.

EDIT: If you're doing that and it's not working (per your comment), I'd look at the middle layers to see what's going on. MySQL is fine with it:

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)
往日 2024-08-14 03:41:39

你在看什么id?您应该能够通过序列(常见场景)获取(比如说)自动生成的主键 ID,无论交易状态如何。您可以发布一些代码来澄清吗?

What id are you looking at ? You should be able to get (say) primary key ids autogenerated via sequences (a common scenario) regardless of a transaction status. Can you post some code to clarify ?

笑脸一如从前 2024-08-14 03:41:39

第一次插入后,您可以

SELECT @@IDENTITY

获取刚刚插入的行的标识吗?

After your first insert, can you do

SELECT @@IDENTITY

To get the identity of the row you just inserted?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文