用两个sql插件进行事务处理

时间:2009-10-09 13:29:42

标签: java mysql spring transactions lastinsertid

我有两个要执行的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 ,因此在B中插入null。

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

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

答案 2 :(得分:0)

第一次插入后,你能做到吗

SELECT @@IDENTITY

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