2013-04-07 56 views
5

我正在學習MySQL事務。我已經搜索了這個答案,但他們似乎都使用PHP來做我想做的工作。下面是我想要做的例子:如何判斷mysql插入是否成功

  1. 開始事務
  2. 更新表1
  3. 插入到表2
  4. 如果插入成功, 一個。然後插入到Table3中並提交。 b。否則回滾事務。

我不明白如何以編程方式確定在步驟3插入是否成功。當然,我可以查詢表格並查看,但我認爲有一些方法可以使用返回值,但似乎只有在我使用PHP來執行事務時纔有效。

這是我想要的代碼塊 - 這是行不通的:

begin; 
start transaction; 
-- attempt to reduce inventory 
update store_inventory set item_qty = item_qty - 2 where id = 1; 
update store_inventory set item_qty = item_qty -1 where id = 5; 

-- insert the order record and check whether it succeded 
insert into store_orders (purchaser_name, purchase_date) 
values ('test user', now()); 
    -- if successful, do final insert and commit 
if Row_Count() > 0 Then  
insert into store_inventory (order_id, inventory_id, item_qty) 
values (1, 1, 2), 
     (1, 2, 1); 
commit; 
else -- otherwise rollback 
rollback; 
end if; 

end; 
+2

您使用什麼語言和適配器來嘗試和執行這些操作? – 2013-04-07 04:16:20

+0

我正在使用MySQL Workbench查詢編輯器。 – 2013-04-07 04:22:10

+0

因此,您正試圖查看插入是否在以下查詢中成功? – 2013-04-07 04:23:07

回答

2

答案是Itay Moav-Malimovka和Gordon的答案的混合。

start transactioncommit之間的所有內容都是一個原子動作。只是這樣寫:

start transaction; 
-- attempt to reduce inventory 
update store_inventory set item_qty = item_qty - 2 where id = 1; 
update store_inventory set item_qty = item_qty -1 where id = 5; 

-- insert the order record 
insert into store_orders (purchaser_name, purchase_date) 
values ('test user', now()); 
insert into store_inventory (order_id, inventory_id, item_qty) 
values (1, 1, 2), 
     (1, 2, 1); 
commit; 

或者讓我解釋一個更簡單的例子是怎麼回事。現在

create table foo(id int primary key); 
insert into foo values (1); 

,如果你有這樣的代碼:

start transaction; 
insert into foo values(2); 
insert into foo values(1); 
insert into foo values(3); 
commit; 

當被插入值1因爲它違反了主鍵,與1已經存在的項目和代碼,就發出一個錯誤以下將永遠不會被執行。如果您現在執行select * from foo;,您會看到表格中有一個值爲2。但這可能只是你在那裏看到2,這取決於隔離級別(你可能想閱讀這些內容)。這是因爲交易尚未完成。現在取決於您,如果您不在意並繼續插入值3並提交或回滾。 但是這是在應用程序級完成的。只需檢查是否有錯誤,如果有人被回滾,如果沒有,一切都很好。有無需檢查交易,因爲如果任何東西出錯/ 插入失敗,檢查是否有失敗的代碼永遠不會到達。

+0

謝謝@tombom。我認爲我只是走錯了路;認爲它可以在一個事務中完成,並且只需在MySQL本身內完成 - 而無需使用存儲的proc。 – 2013-04-07 18:42:05

+0

我不確定你是否理解我的正確。你可以在存儲過程中做到這一點,但你不必這樣做。 – fancyPants 2013-04-07 20:10:00

0

如果所有查詢都在同一個事務中,那麼它被認爲是一個原子操作。 ALL成功或ALL失敗。
無需同時檢查和使用交易。

+0

但是,直到我將其還原或提交後,交易纔會結束。如果我不知道插入到table2中的成功/失敗,我怎麼知道要使用哪個命令?您的評論似乎表明這兩個命令是無用的。 – 2013-04-07 04:25:12

1

你可能會需要存儲過程,但我可能是錯誤的,因爲這是一個需求。您需要自己設置交易並進行一些測試。

DELIMITER $$ 
CREATE PROCEDURE `sample`(name VARCHAR(100)) 
BEGIN 
    START TRANSACTION; -- Begin a transaction 
    INSERT INTO `users` (`name`) VALUES name; 
    IF ROW_COUNT() > 0 THEN -- ROW_COUNT() returns the number of rows updated/inserted/deleted 
     COMMIT; -- Finalize the transaction 
    ELSE 
     ROLLBACK; -- Revert all changes made before the transaction began 
    END IF 
END$$ 
DELIMITER ; 

像這樣的東西可能工作(這是未經測試,純粹是從研究拼湊起來的),你將不得不使用的InnoDB作爲存儲引擎,因爲的MyISAM不支持事務。

+1

http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_row-count – mbrownnyc 2013-06-28 18:58:00

0

如果您使用的是Java和JPA,那麼您可以在用於執行插入的bean中使用註釋 @TransactionManagement(TransactionManagementType.CONTAINER)。這將確保如果事務失敗,容器將撤銷所有更改。你可以谷歌EJB 3.0閱讀更多關於交易管理

相關問題