是否所有受影响的表都被mySQL事务“锁定”了?

时间:2013-04-12 22:14:30

标签: mysql transactions

我想进行金融交易,但我并不熟悉MySQL交易功能。

我想确保我做的一切正常。我的目标是在交易期间“锁定”我的transactionHistory和transactionQueued表,以确保帐户余额是正确的,并且不能插入任何其他事务来操纵余额/同时。

SET autocommit=0;
START TRANSACTION;

IF (
SELECT SUM(amount) of transactionHistory WHERE account = 1
+
SELECT SUM(amount) of transactionsQueued WHERE account = 1)

 >= :amount)

INSERT INTO transactionHistory (account, amount) VALUES (1, -:amount);
INSERT INTO transactionHistory (account, amount) VALUES (2, :amount);

COMMIT;

mySQL锁定所有受影响的表是对的吗?在这种情况下,transactionHistory和transactionsQueued。

我使用的是innoDB,此代码不是程序的一部分。

谢谢!

2 个答案:

答案 0 :(得分:4)

SET autocommit=0;
START TRANSACTION;

两者基本上都是一样的,只是START TRANSACTION也会重新召回会话所持有的所有LOCKS。

如果要锁定TABLE(S)中的记录,则可以使用SELECT ... FOR UPDATE语句(这将锁定落入该SELECT中写入条件的所有记录)。您需要在事务中使用它。

或者你可以锁定整张桌子。要锁定表格,您不能使用START TRANSACTION;然而。你需要像这样开始交易:

SET autocommit=0;
LOCK TABLES transactionHistory as t1 WRITE, transactionsQueued  as t2 READ, ...;
... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;

答案 1 :(得分:1)

了解您正在使用INNODB,答案是否定的,锁定级别为ROW,而不是TABLE(与MYISAM不同)

请参阅此链接:http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-model.html


我想你已经知道了,但你的代码是伪代码,不会像这样工作。 IF语句非常具有程序性,需要包含在BEGIN END块中,否则您可以构建等效的高级insert select语句。