RollBack () and beginTransaction() not work in my PHP PDO and my table type is innoDB. In the following code my $sql1 is correct and my $sql2 is wrong (I added d to $last_id to just make it wrong). But it still executes sql1 meaning roll back no effect. Thank you for your advice.
<?php
include 'connect.php';
// Get multiple input field's value
try {
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Starts our transaction
$conn->beginTransaction();
foreach ($_POST['phone'] as $value) {
$sql1 = "INSERT INTO tbl_contact_info (type)
VALUES ('$value')";
// use exec() because no results are returned
$conn->exec($sql1);
$last_id = $conn->lastInsertId();
$sql2="INSERT INTO tbl_img (img_type)
VALUES ('$dlast_id')";
$conn->exec($sql2);
}
// Commits out queries
$conn->commit();
echo "New record created successfully";
}
catch(PDOException $e)
{
// Something borked, undo the queries!!
$conn->rollBack();
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
First of all (and sorry it it's obvious but I realised it's not always clear to everyone) SQL and PHP are different languages. MySQL Server will not react to Undefined variable notices triggered in PHP code.
Secondly, notices are not exceptions so they cannot be caught with try/catch statements. (You can certainly write a custom error handler that will throw exceptions on errors but it doesn't seem to be the case here.)
Related
I am attempting to insert some data via prepared statements in PHP. I have the following code which is not inserting for me. I also have the following code set already
ini_set('display_errors', 1);
error_reporting(~0);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$sqlInsert = "INSERT INTO deck_cards (deckid, cardid, qty) VALUES (?,?,?)";
$stmtInsert = $conn->prepare($sqlInsert);
if ($stmtInsert)
{
$stmtInsert->bind_param("sss", $deckid, $cardid, $cardcount) or trigger_error($stmtInsert->error, E_USER_ERROR);
$stmtInsert->execute() or trigger_error($stmtInsert->error, E_USER_ERROR);
echo "Check if this ran";
}
else {
echo "Error: " . $sql . "<br>" . $conn->error;
$conn->close();
}
$stmtInsert->close();
}
catch (Exception $ex)
{
echo 'Exception occurred '.$ex->getTraceAsString();
}
When this executes, I do see the text "Check if this ran" but no other messages. The data is not inserted into the database. Additionally, I echo'd the sql string and variables and ran it against the MySQL directly and it inserted ok. Not sure what is happening in my very straightforward code above.
Additionally, inserts are happening ok in other pages within my app, but this page for some reason isn't working.
I know it's overkill on my error reporting, but I threw everything I could think of to see if there is an error somewhere, but this one is a head scratcher for me. Thanks for any assistance!
In my MySQL database very rarely I get duplicate rows. I'm just looking at my code and I want to check if my transaction code is causing this problem. Here is it:
try
{
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$con->beginTransaction();
$sql1 = $con->prepare("query_to_update_tb1");
$sql2 = $con->prepare("query_to_insert_tb2");
$sql1->execute();
$sql2->execute();
...
$sql3 = $con->prepare("query_to_insert_tb1");
$sql4 = $con->prepare("query_to_insert_tb2");
$sql3->execute();
$sql4->execute();
$con->commit();
}
catch(Exception $e)
{
$con->rollback();
}
Never mind. The user was submiting multiple forms, then the duplicate fields. Nothing wrong with the code.
I have a transaction that does an insert into several tables. I want to catch any errors so that if any of the inserts fail they will all be rolled back. Here is a short version of what I am trying to do:
try {
$this->conn->beginTransaction();
//build an sql insert...
$sql = "INSERT INTO...
$stmt = $this->conn->prepare($sql);
$stmt->execute();
//do more inserts...
//commit the transaction
$this->conn->commit();
$this->message = 'The Program has been added.';
//catch errors and rollback
} catch (PDOException $e) {
$this->message = $e->getMessage();
$this->conn->rollBack();
}
All of the inserts work properly but if there is a problem, I don't seem to be catching the error and the rollback does not happen. For instance, if I write bad sql or don't pass values for parameters, I just get php errors but the inserts proceed anyway. I can post the full code if it helps but maybe it is something obvious?
I have writen this pice of code that should insert into my Database some event data, but it does not insert a thing in the DB, can you tell me why?
try {
$pdo = new PDO("mysql:host={$dbhost};dbname={$dbname}", $dbuser, $dbpass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch( PDOException $excepiton ) {
echo "Connection error :" . $excepiton->getMessage();
}
try{
$sql = "INSERT INTO events_DB (event_id, event_end_time, event_location, event_name) VALUES (:event_id, :event_end_time, :event_location, :event_name) ON DUPLICATE KEY UPDATE event_id = :event_id, event_end_time = :event_end_time, event_location = :event_location, event_name = :event_name";
$stm = $db->prepare($sql);
$stm->execute(array(":event_id" => $event[id], ":event_end_time" => $event[end_time], ":event_location" => $event[location], ":event_name" => $event[name]));
}
catch ( PDOException $exception )
{
// decomentati sa vedeti erorile
echo "PDO error :" . $exception->getMessage();
}
Thanks
The code you've posted is different than the code you're running as the posted code would result in a syntax error at parse time and never actually run.
However, what's happening is the SQL being sent to the prepare method is not valid in some way so that the result returned and stored in $stm is a boolean (false) rather than a valid statement object. Double check your SQL (you could try running it in another application such as phpMyAdmin or via the mysql command-line program) to ensure its validity. You could also add some error handling to find the cause with:
$stm = $db->prepare($sql);
if (!$stm) {
die($db->errorInfo());
}
Edit: You've modified the posted source code which now shows use of exception handling. However, you've commented out the line that echos the exception message. This information will be useful in telling you what's causing the error condition. Uncomment to see the message (which will most likely inform you that the SQL is invalid and which part of it caused the error).
Try to remove the <br> tag from the first line and a " is messing
$sql = "INSERT INTO events_DB (event_id, event_end_time, event_location, event_name);"
Well basically I have this script that takes a long time to execute and occasionally times out and leaves semi-complete data floating around my database. (Yes I know in a perfect world I would fix THAT instead of implementing commits and rollbacks but I am forced to not do that)
Here is my basic code (dumbed down for simplicity):
$database = new PDO("mysql:host=host;dbname=mysql_db","username","password");
while (notDone())
{
$add_row = $database->prepare("INSERT INTO table (columns) VALUES (?)");
$add_row->execute(array('values'));
//PROCESSING STUFF THAT TAKES A LONG TIME GOES HERE
}
$database = null;
So my problem is that if that if the entire process within that while loop isn't complete then I don't want the row inserted to remain there. I think that somehow I could use commits/rollbacks at the beginning and end of the while loop to do this but don't know how.
Take a look at this tutorial on transactions with PDO.
Basically wrap the long running code in:
$dbh->beginTransaction();
...
$dbh->commit();
And according to this PDO document page:
"When the script ends or when a connection is about to be closed, if you have an outstanding transaction, PDO will automatically roll it back. "
So you will lose the transaction that was pending when the script timed out.
But really, you ought to redesign this so that it doesn't depend on the scriipt staying alive.
You need to use InnoDB based tables for transactions then use any library like PDO or MySQLi that supports them.
try
{
$mysqli->autocommit(FALSE);
$mysqli->query("insert into tblbook (id,cid,book) values('','3','book3.1')");
echo $q_ins=$mysqli->affected_rows."<br>";
$mysqli->query("update tblbook set book='book3' where cid='3'");
echo $q_upd=$mysqli->affected_rows."<br>";
$mysqli->commit();
}
catch(PDOException $e)
{
$mysqli->rollback();
echo $sql . '<br />' . $e->getMessage();
}
<?php
//This may help someone....This code commit the transactions
//only if both queries insert and update successfully runs
$mysqli=new mysqli("localhost","user_name","password","db_name");
if(mysqli_connect_errno())
{
echo "Connection failed: ".mysqli_connect_error();
}
else
{
$mysqli->autocommit(FALSE);
$mysqli->query("insert into tblbook (id,cid,book) values('','3','book3.1')");
echo $q_ins=$mysqli->affected_rows."<br>";
$mysqli->query("update tblbook set book='book3' where cid='3'");
echo $q_upd=$mysqli->affected_rows."<br>";
if($q_ins==1 && $q_upd==1)
{
$mysqli->commit();
echo "Commit<br>";
}
else
{
$mysqli->rollback();
echo "Rollback<br>";
}
}
?>