为了账号安全,请及时绑定邮箱和手机立即绑定

如何检测 2 个管理员是否在 php 中同时更新表行

如何检测 2 个管理员是否在 php 中同时更新表行

PHP
白猪掌柜的 2021-06-30 13:49:54
我正在开发的网站有一个管理页面,用于将产品添加到数据库或编辑数据库中的现有产品。如果两个管理员想要编辑同一个产品,第二个管理员应该收到产品已经/正在更新的警报。当 2 个管理员尝试编辑同一个产品时,我如何在 php/sql 中检测到?我还没有真正尝试过任何东西,因为我不知道该尝试什么或从哪里开始。这是我的函数如何查找更新数据库中的产品://I know this is a VERY unsafe function, this website will never go online!FUNCTION updateProduct($data) {  include_once 'dbconn.php';  try {    $conn = connectToDb();    if ($data['imageChanged'] == false) {      $query = "SELECT img_url FROM products WHERE product_id=".$data['productId'];      $result = mysqli_query($conn, $query);      if ($result == false) {        throw new Exception('Failed to execute: '. $query . 'Error: '. mysqli_error($conn));      }      $imgUrl = mysqli_fetch_row($result)[0];    } else {      $imgUrl = $data['image'];    }    $query2 = "img_url='".$imgUrl."'";    $query = "UPDATE products              SET product_name='".$data['productName']."', product_desc='".$data['productDesc']."', price=".$data['price'].", ". $query2 . "               WHERE product_id=".$data['productId'];    $result = mysqli_query($conn, $query);    if ($result == false) {      throw new Exception('Failed to execute: '. $query . 'Error: '. mysqli_error($conn));    }  } finally {    mysqli_close($conn);  }}编辑:不需要在更新后存储旧数据,也不需要存储正在进行的更新(关于这可能是重复的问题)。我想知道的是:如果 admin_1 正在更新一行,而 admin_2 正在尝试在 admin_1 的事务仍在进行时更新同一行,我的脚本如何检测到这种情况正在发生?
查看完整描述

2 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

考虑以下几点 1) 您希望多个管理员编辑不同的产品 2) 您不希望多个管理员编辑同一产品


3)在您的代码中,您将产品保存为单个表。在一个真实的电子商务网站产品信息被拆分成几个表格


要实现这一点,您必须设置应用程序范围的 mysql 锁


mysql> select get_lock('product_id_12345', 5);

+---------------------------------+

| get_lock('product_id_12345', 5) |

+---------------------------------+

|                               1 |

+---------------------------------+

1 row in set (0.00 sec)


上面的代码使用 product_id 设置了一个锁,如果其他一些连接尝试使用相同的 product_id 获取锁,你将得到 0 作为响应 - 表明其他一些用户正在更新相同的 product_id


mysql> 

mysql> select IS_FREE_LOCK('product_id_12345');

+----------------------------------+

| IS_FREE_LOCK('product_id_12345') |

+----------------------------------+

|                                0 |

+----------------------------------+

1 row in set (0.00 sec)


mysql> 

mysql> select IS_USED_LOCK('product_id_12345');

+----------------------------------+

| IS_USED_LOCK('product_id_12345') |

+----------------------------------+

|                               46 |

+----------------------------------+

1 row in set (0.00 sec)


mysql> 

mysql> select connection_id();

+-----------------+

| connection_id() |

+-----------------+

|              46 |

+-----------------+

1 row in set (0.00 sec)


示例算法


<?php

ini_set('display_errors', 1);


function updateProduct() {


$user = 'root';

$pass = 'xxx';

$DB = 'test';

$host = 'localhost';


  try 

  {

    $conn = new mysqli($host, $user, $pass, $DB);



    $data['productId'] = 'product_id_12345';

    $data['productName'] = 'test';

    $data['productDesc'] = 'testing';


    $isLockFree = 'select IS_USED_LOCK("'.$data['productId'].'") ';

    $isLockFreeResult = mysqli_query($conn, $isLockFree);

    $row=mysqli_fetch_row($isLockFreeResult);


    if(empty($row[0]))

    {

        $lock = 'select get_lock("'.$data['productId'].'")';

        $result = mysqli_query($conn, $lock);


        echo 'lock established';


        $query = "UPDATE products

                  SET product_name='".$data['productName']."', 

                      product_desc='".$data['productDesc']."', 

                      price=".$data['price']."

                  WHERE 

                  product_id=".$data['productId'];


        $result = mysqli_query($conn, $query);

        if ($result == false) 

        {

          throw new Exception('Failed to execute: '. $query . 'Error: '. mysqli_error($conn));

        }

    }

    else

    {

        echo 'sorry! could not lock. somebody is updating the product info';

    }

  } 

  finally 

  {

    mysqli_close($conn);

  }

}

updateProduct();

?>


查看完整回答
反对 回复 2021-07-09
  • 2 回答
  • 0 关注
  • 100 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信