代码之家  ›  专栏  ›  技术社区  ›  Alberto Zaccagni

具有两个sql insert的事务

  •  3
  • Alberto Zaccagni  · 技术社区  · 15 年前

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

    在第二个insert中,我需要来自第一个insert的id,但是在对事务进行提交之前,我不会得到这个id。
    所以我被困住了。我不想从事务中删除第一个insert,可能第一个insert正常,而第二个则不正常,这使我在数据库中的状态不一致。

    在这种情况下,最佳做法是什么?

    编辑:代码如下:

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

    我想指出的是我不明白

    3 回复  |  直到 15 年前
        1
  •  2
  •   T.J. Crowder    15 年前

    在MySQL上,在 insertIntoA 你应该能够做到:

    SELECT LAST_INSERT_ID()
    

    identity 要查找的列值。

    编辑

    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)
    
        2
  •  1
  •   Brian Agnew    15 年前

    你在看什么证件?您应该能够获得(比如)通过序列自动生成的主键ID(一个常见的场景) 不管

        3
  •  0
  •   Paul    15 年前

    SELECT @@IDENTITY
    

    获取刚插入的行的标识?