关于MySQL / PHP中的事务(或表锁?)的问题

时间:2014-04-10 15:41:36

标签: php mysql sql

我有一个看似非常基本的问题,但我找不到最有效的解决方案。

假设我有这个表,表KEYS

KEYS
KEY_ID        VALUE        USED
1             123ASD       1
2             ASD234       0
3             123456       0

我希望有一个API(这里称之为get_key.php)将使用used = 0访问db的最后一个值,返回JSON格式的密钥以通过ajax解释给用户,然后标记数据库中使用的密钥。

我已经看过关于锁定表的想法,但我担心的是有一个脚本不断生成并将密钥插入数据库,而大量用户将请求密钥。

实现这一目标的最佳方法是什么,同时仍然可以安全地防止发送重复条目,表锁会导致网页传送的长时间延迟,并且仍然能够在检索时插入?

如果你仍然感到困惑,这是一个基本的例子......

get_key.php

//not real file just pseudo
//(lock table?)
//SELECT VALUE, KEY_ID FROM `KEYS` WHERE USED = 0 LIMIT 1;
//$key = $response['VALUE']
//echo out key in json format
//$key_id = $response['KEY_ID']
//UPDATE `KEYS` SET USED = 0 WHERE KEY_ID = $key_id;
//(unlock table?)

insert_key.php

//$key = $_GET['value']
//(lock tables?)
//INSERT INTO `KEYS` (VALUE) VALUES ($key)
//(unlock tables?)

我知道生产设置中的这个设置会非常不安全,但要尽可能简单,以便您能够正确理解我的问题。

非常感谢您的时间!

1 个答案:

答案 0 :(得分:0)

使用InnoDB或任何其他支持行级锁的引擎。然后你只需要锁定你正在选择/更新的那一行,例如

SELECT VALUE, KEY_ID
FROM `KEYS`
FOR UPDATE  // <--- add this row
WHERE USED = 0 LIMIT 1;

... do other stuff

UPDATE `KEYS`
SET USED = 1
WHERE KEY_ID = xxx;

COMMIT;

MySQL将锁定它找到的记录,然后只有这个特定的数据库连接才能修改该记录,直到它解锁或连接关闭。