如何判断mysql插入是否成功

时间:2013-04-07 04:14:57

标签: mysql

我正在学习MySQL交易。我已经搜索了这个问题的答案,但他们似乎都使用PHP来制作我想做的工作。以下是我尝试做的例子:

  1. 开始交易
  2. 更新表1
  3. 插入表2
  4. 如果插入成功, 一个。然后插入表3并提交。 湾否则回滚交易。
  5. 我不明白如何以编程方式确定步骤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;
    

4 个答案:

答案 0 :(得分: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并提交或回滚。 但是这是在应用程序级别完成的。只需检查一个错误,如果有人提出回滚,如果没有,一切都很好。 无需在交易内部进行检查,因为如果出现任何问题/ 插入失败,将无法检查是否有任何失败的代码。

答案 1 :(得分: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 不支持交易

答案 2 :(得分:0)

如果所有查询都在同一个事务中,那么它被认为是一个原子操作。 ALL 成功或 ALL 失败 无需同时检查和使用交易。

答案 3 :(得分:0)

如果您使用的是java和JPA,则可以使用注释 你用来做插入的bean中的@TransactionManagement(TransactionManagementType.CONTAINER)。这将确保如果事务失败,容器将撤消所有更改。你可以谷歌EJB 3.0阅读有关交易管理的更多信息