"PDO :: commit()"메소드를 "try"블록에 넣으면 작동하지 않고 "commit"을 얻지도 않습니다. SQL- 코드는 괜찮습니다.PHP/PDO :: commit이 "try"블록에서 작동하지 않습니다.
$conn->dbh->beginTransaction();
$stmt = $conn->dbh->prepare('some SQL-code');
$stmt->bindValue(...);
try
{
$stmt->execute();
$conn->dbh->commit();
}
catch (Exception $e)
{
$dbh->rollBack();
echo $e->getMessage();
}
그러나 "catch"블록을 넣으면 모든 것이 올바르게 작동합니다.
...
try
{
$stmt->execute();
}
catch (Exception $e)
{
$dbh->rollBack();
echo $e->getMessage();
}
$conn->dbh->commit();
이것은 예상되는 동작이며 PDO :: commit()이 "try"블록에서 작동하지 않는 이유는 무엇입니까?
이 문제에 대한 해결책을 찾기 위해 전체 2 시간을 소비했기 때문에 자신을 명확히하고 싶습니다. 솔루션이 올바른지 확실하지 않습니다. 나는 준비된 문장 당 하나 개의 쿼리를 가질 수 있도록 코드를 다시 작성하려고했습니다
Class Connection
{
public $dbh;
private static $instance;
private function __construct()
{
$config = parse_ini_file('config.ini');
$dsn = $config['db.dbms'] . ':host=' . $config['db.host'] .
';dbname=' . $config['db.dbname'] .
';port=' . $config['db.port'] .
';connect_timeout=15';
$this->dbh = new PDO($dsn, $config['db.user'], $config['db.password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public static function getInstance()
{
if (!isset(self::$instance))
{
$object = __CLASS__;
self::$instance = new $object;
}
return self::$instance;
}
}
Class NestedSet
{
public function insertAsLastChildOf ($parentnode)
{
$fields = '';
$params = '';
$conn = Connection::getInstance();
$conn->dbh->beginTransaction();
foreach ($this->_modelfields as $field => $type)
{
$fields .= '`'.$field.'`, ';
$params .= ':'.$field.', ';
}
$stmt = $conn->dbh->prepare('UPDATE `' . $this->_tablename . '`
SET `rgt` = `rgt` + 2
WHERE `rgt` >= :parentnodergt;
UPDATE `' . $this->_tablename . '`
SET `lft` = `lft` + 2
WHERE `lft` > :parentnodergt;
INSERT INTO `' . $this->_tablename . '`
(' . $fields . '
`lft`,
`rgt`,
`level`)
SELECT
' . $params . '
`rgt` - 2,
`rgt` - 1,
`level` + 1
FROM `' . $this->_tablename . '`
WHERE `id` = :parentnodeid;');
foreach ($this->_modelfields as $field => $type)
{
$pdoparam = (stripos($type, 'int') === 0) ? PDO::PARAM_INT : PDO::PARAM_STR;
$stmt->bindValue(':'.$field.'', $this->$field, $pdoparam);
}
$stmt->bindValue(':parentnodergt', $parentnode->rgt, PDO::PARAM_INT);
$stmt->bindValue(':parentnodeid', $parentnode->id, PDO::PARAM_INT);
try
{
$stmt->execute();
$conn->dbh->commit();
}
catch (PDOException $e)
{
$conn->dbh->rollBack();
echo $e->getMessage() . '<br/> file - ' . __FILE__ . '<br/> line - ' . __LINE__ . '<br/>';
}
unset($stmt);
}
}
:
여기에 코드입니다. 그 경우에는 모든 것이 잘 작동합니다. 오류가없고 예외가 발생하면 코드가 실행되고 그렇지 않으면 롤백됩니다.
다음은이 PDO는 ::) (준비 여러 쿼리와 함께 사용되어서는 안된다는 뜻 코드
$stmt_1 = $conn->dbh->prepare('UPDATE `' . $this->_tablename . '`
SET `rgt` = `rgt` + 2
WHERE `rgt` >= :parentnodergt;');
$stmt_1->bindValue(':parentnodergt', $parentnode->rgt, PDO::PARAM_INT);
$stmt_2 = $conn->dbh->prepare('UPDATE `' . $this->_tablename . '`
SET `lft` = `lft` + 2
WHERE `lft` > :parentnodergt;');
$stmt_2->bindValue(':parentnodergt', $parentnode->rgt, PDO::PARAM_INT);
$stmt_3 = $conn->dbh->prepare('INSERT INTO `' . $this->_tablename . '`
(' . $fields . '
`lft`,
`rgt`,
`level`)
SELECT
' . $params . '
`rgt` - 2,
`rgt` - 1,
`level` + 1
FROM `' . $this->_tablename . '`
WHERE `id` = :parentnodeid;');
foreach ($this->_modelfields as $field => $type)
{
$pdoparam = (stripos($type, 'int') === 0) ? PDO::PARAM_INT : PDO::PARAM_STR;
$stmt_3->bindValue(':'.$field.'', $this->$field, $pdoparam);
}
$stmt_3->bindValue(':parentnodeid', $parentnode->id, PDO::PARAM_INT);
try
{
$stmt_1->execute();
$stmt_2->execute();
$stmt_3->execute();
$conn->dbh->commit();
}
catch (PDOException $e)
{
$conn->dbh->rollBack();
echo $e->getMessage() . '<br/> file - ' . __FILE__ . '<br/> line - ' . __LINE__ . '<br/>';
}
unset($stmt);
입니까?
나는 PDO 매뉴얼에서 그 사실을 발견하지 못했기 때문에 묻습니다.
PDO 인스턴스의 예외 처리를 활성화 했습니까? – hakre
예, Connection 클래스 (Singleton)의 __construct()에 다음과 같이 입력했습니다 :'$ this-> dbh = new PDO (. ..); $ this-> dbh-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); 그리고 SQL 코드에 오류가 있으면 예외가 발생합니다. – Placido
예외를 유발하고 실제로 작동하는지 확인하십시오. – hakre