简体   繁体   中英

how to tell if a mysql insert is successful

I'm learning MySQL transactions. I've searched for answers to this, but they all seem to use PHP to make what I want to do work. Here's the example of what I'm trying to do:

  1. Begin the transaction
  2. Update Table1
  3. Insert into Table2
  4. If Insert is successful, a. then insert into Table3 and commit. b. else rollback the transaction.

I don't understand how to determine programmatically whether the insert at step 3 was successful. Sure, I can query the table and see, but I thought there was some way to use the return value, but it seems that only works when I'm using PHP to do the transaction.

This is the code block for what I'm trying - it doesn't work:

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;

The answer is a mix of Itay Moav-Malimovka and Gordon's answer.

Everything between start transaction and commit is one atomic action. Just write it like this:

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;

Or let me explain it on an easier example what's going on.

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

Now, if you have code like this:

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

An error is raised when the value 1 gets inserted because it violates the primary key, an entry with 1 already exists and the code that follows will never be executed. If you do a select * from foo; now, you will see, that there's a value of 2 in your table. But that's probably just you who sees the 2 in there, that depends on the isolation level (you might want to read about those). This is because the transaction is still pending. Now it's up to you, if you don't care and continue with inserting value 3 and commit or you rollback. BUT this is done on application level. Simply check for an error, if one was raised rollback, if not, everything's fine. There's no need to check inside the transaction , because if anything goes wrong / the insert fails, the code for checking if anything failed will never be reached.

You're probably going to need stored procedures, but I may be wrong on that being a requirement. You'll need to setup transactions yourself and do some testing.

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 ;

Something like this may work (this is untested, purely pieced together from research) and you will have to use InnoDB as the storage engine because MyISAM does not support transactions.

IF all queries are inside the same transaction, then it is considered one atomic action. Either ALL succeed or ALL fail.
No need to both check AND use transactions.

if you are using java and JPA you can use the annotation @TransactionManagement(TransactionManagementType.CONTAINER) in the bean you are using to do inserts. this will ensure that if a transaction fails the container will undo all changes. you can google EJB 3.0 to read more about transaction management

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM