0

我想做一笔金融交易,但我对 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,并且此代码不是过程的一部分。

谢谢!

4

2 回答 2

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;
于 2014-02-07T15:28:01.620 回答
1

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

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


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

于 2013-04-12T22:25:11.033 回答