2009-10-09 68 views
3

我有兩個sql插入操作(比如表A和B中的示例),它們在事務中,因爲我希望數據庫保持一致,即A中的元組必須具有引用在B.使用兩個sql插入事務

在第二次插入我需要來自第一個ID,但我沒有得到這個ID,直到我對事務提交。
所以我卡住了。我不想將第一個插入從事務中移出,可能會發生第一個插入正常但第二個插入不正常,導致數據庫中的狀態不一致。

這種情況下的最佳做法是什麼?

編輯:這裏是代碼:

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

我想指出的是,我沒有得到援助直到我提交事務,因此將空到B.

+1

insertIntoA()包含什麼? – 2009-10-09 13:39:49

+0

它包含一個DAO調用,然後調用iBatis插入A中的對象。 – 2009-10-09 14:00:00

回答

1

什麼你在看什麼?您應該能夠通過序列(常見場景)(無論是)獲得(說)主鍵ID。你可以張貼一些代碼來澄清?

+0

我編輯了我的問題以包含示例代碼。 – 2009-10-09 13:39:01

+0

請問您能否擴展「不論交易狀態如何」?特別是在像Spring這樣的情況下。 – 2009-10-09 14:18:19

0

您第一次插入後,你可以做

SELECT @@IDENTITY 

爲了讓您剛插入的行的標識?

+0

哎呀抱歉 - 多數民衆贊成sql ... – Paul 2009-10-09 13:33:55

+0

我已經在iBatis的水平,我的問題是,由於查詢還沒有完成(代碼是在交易中),aId爲空 – 2009-10-09 13:46:59

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) 
+0

我已經完成那是我通常這樣做的,但在這種情況下,我認爲它是不同的。在上面的代碼中,我沒有在賦值中找到aId,因爲事務尚未提交。這有道理嗎? – 2009-10-09 13:49:49

+0

好吧,我知道mysql中的事務按預期工作,但是,我有中間的Spring,這是我認爲的差異。 – 2009-10-09 14:13:38

+0

也許吧。祝你好運。 – 2009-10-09 14:24:51