【问题标题】:I want to achieve row level locking using php in mysql我想在mysql中使用php实现行级锁定
【发布时间】:2023-03-08 06:33:01
【问题描述】:

我正在设计这个页面,用户可以在其中看到当天的变更单。我只希望一个人一次编辑一个变更单。而其他用户仍然可以编辑其他变更单。我粘贴的代码是用于在单击特定更改订单后重定向用户的最终页面。请举个例子帮助我,因为我对 php 和 mysql 很陌生。提前致谢。 `

<?php
$change = $_GET['value'];
mysqli_query('BEGIN');
$sql="SELECT  * FROM cat_firewall USE INDEX(id) WHERE chg_id='$change' FOR UPDATE";
$result=mysqli_query($con,$sql);

// Count table rows 
$count=mysqli_num_rows($result);
?>
---MORE CODE----
while ($row = mysqli_fetch_array($result)){ ?>
        <tr>
---MORE CODE----

<?php

$source_FW = $_POST['source_FW'];
$source_ACL =  $_POST['source_ACL'];
$destination_FW = $_POST['destination_FW'];
$destination_ACL =  $_POST['destination_ACL'];


if(isset($_POST['Submit'])){


foreach($source_FW as $key=>$value){
$sql1="UPDATE cat_firewall SET source_FW='$value' WHERE entry_id='$key' AND chg_id='$change' ";
$result=mysqli_query($con,$sql1);
}
foreach($source_ACL as $key1=>$value1){
$sql2="UPDATE cat_firewall SET source_ACL='$value1' WHERE entry_id='$key1' AND chg_id='$change'  ";
mysqli_query($con,$sql2);
}
foreach($destination_FW as $key2=>$value2){
$sql3="UPDATE cat_firewall SET destination_FW='$value2' WHERE entry_id='$key2' AND chg_id='$change' ";
mysqli_query($con,$sql3);
}
foreach($destination_ACL as $key3=>$value3){
$sql4="UPDATE cat_firewall SET destination_ACL='$value3' WHERE entry_id='$key3' AND chg_id='$change'  ";
mysqli_query($con,$sql4);
}

echo "update complete";
}

sleep(120);
mysqli_query($con,'COMMIT');
?>'

`

【问题讨论】:

  • @JayantRaizada 对于这种类型的锁定,您需要考虑很多问题。您如何确定用户仍在查看订单?如果他们让浏览器选项卡打开 24 小时怎么办?如果他们关闭了浏览器选项卡,或者他们的计算机在打开但未提交更改的情况下崩溃了怎么办?
  • 如果你想在用户进入编辑页面时锁定它(在提交更改之前)......那么你可以有一个布尔字段来切换行。但是您还必须跟踪该用户是否在未提交更改的情况下退出编辑页面。变得凌乱。
  • @Devon 我现在不是在寻找那个东西,但我一直在通过创建不同的表并使用它来存储锁详细信息来阅读乐观和悲观的方法。读完后我很困惑。
  • "如果是同一个请求,是的,但如果他们希望在查看页面时锁定它,则不是。" true @Devon CONNECTION_ID() 需要保持不变..
  • 我想在用户单击变更单并进入此页面以编辑行并在单击提交按钮后释放行上的锁定时立即锁定它。

标签: php mysql locking innodb using


【解决方案1】:

我想在用户单击变更单并进入此页面以编辑行并在单击提交按钮后释放对该行的锁定时立即锁定它。

这是一个很大的危险信号。您不应该期望 InnoDB 锁定以人类的冰川速度运行。

光学版:

  • 为发生的更新设置一个序列号。
  • 在用户查看值并挠头时开始获取该数字。
  • 让用户(以极快的速度)进行更改。
  • 现在将更新和序列号发送回执行此操作的客户端 API

以下内容:

BEGIN;
SELECT seq_num ... FOR UPDATE;
if the seq_num has changed, ROLLBACK this transaction and tell the user to start over.
else...
do the UPDATEs
update seq_num to a new number
COMMIT;

悲观的方法...

BEGIN;
SELECT who_is_editing FROM ... FOR UPDATE;
if someone else is editing, ROLLBACK and tell user to "try again later".
else...
UPDATE ... who_is_editing = $this_user;
COMMIT;

现在继续让用户为所欲为。但是,最后,清除who_is_editing

警告:如果用户只是消失了,这个“锁”可能永远不会被释放。所以...

  • 对此进行一些工作检查。
  • 警告用户输入更改的时间有限。
  • 验证在 UPDATE 事务中用户仍然匹配who_is_editing。如果不扇他一巴掌,告诉他“你拖得太久了!”。

(警告:这两种方法都是仓促输入的;请仔细研究,寻找逻辑漏洞。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多