2013-04-07 35 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阅读更多关于交易管理

相关问题