我在PHP和MySQL数据库中使用PDO。我想要做的是每当插入失败时(例如在唯一字段中重复输入),让它抛出异常错误消息并回滚更改(而不是在我的情况下自动递增)。
这就是我所做的,但它不起作用:
try {
$email = $_POST['Email'];
$FirstName = $_POST['FirstName'];
$LastName = $_POST['LastName'];
$query="INSERT INTO subscriber (Email,FirstName,LastName,CreateDate) VALUES (?,?,?,CURDATE())";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $email , PDO::PARAM_STR);
$stmt->bindParam(2, $FirstName, PDO::PARAM_STR);
$stmt->bindParam(3, $LastName, PDO::PARAM_STR);
$stmt->execute();
}
catch(PDOException $e) {
die ($e->getMessage().'<a href="addSub.php"> Back</a>');
$conn->rollBack();
}
我哪里出错了?
这是它的编辑版本(对于插入的整个部分),这是正确的吗?谢谢
if($_SERVER['REQUEST_METHOD'] == "POST"){
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->beingTransaction();
try {
$email = $_POST['Email'];
$FirstName = $_POST['FirstName'];
$LastName = $_POST['LastName'];
$query="INSERT INTO subscriber (Email,FirstName,LastName,CreateDate) VALUES (?,?,?,CURDATE())";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $email , PDO::PARAM_STR);
$stmt->bindParam(2, $FirstName, PDO::PARAM_STR);
$stmt->bindParam(3, $LastName, PDO::PARAM_STR);
$conn->commit();
}
catch(PDOException $e)
{
die ($e->getMessage().'<a href="addSub.php"> Back</a>');
$conn->rollBack();
}
try {
$userID = $_SESSION['username'];
$query="INSERT INTO list_sub (SubID,ListID) VALUES ('',$_SESSION[ListID])";
$stmt = $conn->prepare($query);
$conn->commit();
}
catch(PDOException $e)
{
$conn->rollBack();
die ($e->getMessage().'<a href="addSub.php"> Back</a>');
}
$conn = null;
}
答案 0 :(得分:9)
这就是所有的代码吗?您必须启动事务才能提交/回滚:
$conn->beginTransaction();
try {
....
$conn->commit();
} catch (PDOException $e) {
$conn->rollback();
}
答案 1 :(得分:6)
PHP函数die
是exit的别名,并在打印指定的消息后立即终止执行,因此第二行 - 回滚 - 永远不会执行。
答案 2 :(得分:2)
首先,您使用die()
将退出程序,因此不会执行任何行。
然而,除此之外,您还需要确定其他事项。
首先,确保subscriber
是InnoDB
表格类型。 MySQL(MyISAM
)上的默认表类型不支持事务。
其次,请确保您的PDO
对象PDO::ATTR_ERRMODE
设置为PDO::ERRMODE_EXCEPTION
。您可以在构造函数中设置此属性,也可以使用setAttribute()
。
第三,您需要在$conn->beginTransaction()
子句之前使用try
实际开始交易。
答案 3 :(得分:1)
无法保证AUTOINCREMENT
值是连续的。
如果有两个并行的事务,都插入到同一个表中,那么任何一个都接受编号中有漏洞,或者第二个事务必须等到第一个事务完成才能启动。由于这对性能不利,因此可以实现“漏洞可接受”的变体。
答案 4 :(得分:0)
此语言构造等同于exit()。