Php 如何实现mysql表行的锁定机制以避免竞争条件?

Php 如何实现mysql表行的锁定机制以避免竞争条件?,php,mysql,Php,Mysql,嗨,朋友们,每次加载网页时,我都会更新网站的页面浏览量 这段代码放在页面顶部,现在我的问题是,这种机制可能导致竞争条件我想锁定我的行,直到它被更新。请帮助mysql查询锁定特定行,直到它被更新。您不应该选择然后更新要更新的记录 <?php $time=getdate(); $time['month']; $temp_time=$time['month']." ".$time['year']; $q="SELECT * FROM websiteview

嗨,朋友们,每次加载网页时,我都会更新网站的页面浏览量
这段代码放在页面顶部,现在我的问题是,这种机制可能导致竞争条件我想锁定我的行,直到它被更新。请帮助mysql查询锁定特定行,直到它被更新。

您不应该选择然后更新要更新的记录

    <?php
    $time=getdate();
    $time['month'];
    $temp_time=$time['month']." ".$time['year'];
    $q="SELECT * FROM websiteviews ORDER BY id DESC LIMIT 1";
    $r=mysqli_query($dbc, $q);
    $r=mysqli_fetch_assoc($r);
    if($temp_time==$r['timespan']){
        $count=$r['view']+1;
        $q="UPDATE websiteviews SET view='".$count."' WHERE id='".$r['id']."'";
        mysqli_query($dbc, $q);
        echo mysqli_error($dbc);
    }
    ?>
上面的查询一步更新记录,因此数据库管理系统可以处理竞争条件。您可能应该更改WHERE条件以匹配您的需求

如果列视图可为空,则将设置的部分更改为view=COALESCEview,0+1

存储引擎

在MySQL中,表可以通过不同的存储引擎存储,所有引擎都有不同的锁定支持(如果有的话)


其他资源:

我认为您需要使用事务锁定,但您的表需要使用支持InnoDB之类事务的引擎

你可以阅读更多关于


您可以使用事务来解决竞争条件,如下所示:

UPDATE
  websiteviews
SET
  view = view+1
WHERE
  -- Assuming 'timespan' is a varchar column and the stored format is 'MM YYYY'
  timespan = DATE_FORMAT(NOW(), '%m %Y')

注意:请注意select语句中使用的FOR UPDATE子句。

如果您使用mysqli,您应该真正使用准备好的语句。表类型是什么?表类型是utf-8 oninnoDB@user3787783只是为了澄清,utf-8是一种表类型,而不是一种表类型,它只应用于存储字符数据的列。处理存储的数据如何持久化。存储引擎可以由Engine或TYPE关键字指定。支持TYPE关键字以实现向后兼容性。从3.23.0版到4.0.18版,只有TYPE关键字可用。TYPE关键字现在已弃用。
START TRANSACTION;
SELECT view, id FROM websiteviews ORDER BY id DESC LIMIT 1 FOR UPDATE;

#id obtained from previous step
#view obtained from previous step
UPDATE websiteviews SET `view`=<view>+1 WHERE id= <id>;
COMMIT;