我想进行金融交易,但我并不熟悉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,此代码不是程序的一部分。
谢谢!
答案 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
语句。