PHP PDO事务与嵌套PHP检查

时间:2014-06-04 09:00:02

标签: php mysql sql

我必须做2个MySql查询:

  1. SELECT id FROM X WHERE [...]

  2. INSERT [...]

  3. 如果第一个查询返回正确的id,则只应执行第二个查询。

    是否有可能在两个查询之间混合PHP条件?

    例如

    try
    {   
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $dbh->beginTransaction();   
    
        $stmt =  $dbh->prepare("SELECT id FROM [...]");
    
        $stmt->bindParam(1, [...]);
    
        if($stmt->execute())
        {
            if($row = $stmt->fetch())
            {
                $matchID = $row['id'];
                $checkD = $this->checkId($matchID);
    
                if($checkD)
                {
                    return '-1';
                }
                else
                {       
    
                    $stmt = $dbh->prepare("INSERT INTO [...]");
    
                    $stmt->bindParam(1,[...]);
                    $stmt->execute();
    
                                stmt = $dbh->prepare("DELETE [...]");
    
                    $stmt->bindParam(1,[...]);
                    $stmt->execute();
    
                    $dbh->commit();
    
                    return $matchID;                            
                }
            }
            else
            {
                return '-1';
            }
        }
        else
        {
            return '-1';
        }       
    } catch(Exception $e)
    {
        $dbh->rollBack();
        return '-1';
    }
    

    这是对的吗? (我得到零错误) 如果没有:我怎么能意识到它?

    我想确定,当其他用户执行1.查询时,没有其他用户可以访问INSERT查询。

2 个答案:

答案 0 :(得分:1)

交易与当前数据隔离。它们的行为方式取决于它们使用的isolation level。例如,具有可序列化隔离级别的事务完全存在于过去,并且它不知道自事务开始以来已经进行的数据更改。

如果您想在脚本处理某些内容时阻止任何人对数据库进行更改,那么您必须lock数据库,表或行。使用正确的代码通常不需要这样做。

在你的情况下

  • 您可以使用读取已提交事务隔离级别(默认)在DELETE之后调用SELECT,并在DELETE之前检查INSERT是否存在受影响的行
  • 如果您不想更改查询的顺序,则可以
      如果DELETE不影响任何行,
    • 只会抛出异常,因此INSERT将被回滚
    • 添加一个约束,以防止多个INSERT具有相同的数据,因此重复的INSERT将违反约束,并且将回滚
    • 使用SELECT FOR UPDATE
    • 锁定行

答案 1 :(得分:-1)

这没有任何意义。完全没有交易用途。你要回滚什么? SELECT查询结果?

  

我想确定,当另一个用户执行1.查询时,没有其他用户可以访问INSERT查询。

这是通过表锁定而不是事务来实现的。或者,而不是简单的密钥唯一性。如果不了解您的业务逻辑,就无法回答更多问题。更好地提出另一个问题,解释用户体验,避免使用像" transaction"等技术术语。一点都不。