try catch issue with deadlock - php

i use below code -Just try again. - to prevent deadlock.
it seems when code goes to catch part query2 run before query1.
and i see this output "query2 run before query 1";
is it true?
try
{
$query1="....";
}
catch
{
$query1="....";//repeat query1 in try
$t1=microtime();
}
$query2="....";
$t2=microtime();
if ($t2<$t1)
{
echo "query2 run before query 1";
}

No it's not true
echo '1';
try {
echo '2';
throw new Exception;
} catch (Exception $e) {
echo '3';
}
echo '4';
// Prints 1234

Related

Rolling back MySQL queries

If I have multiple queries on chain, on a structure based on IFs, like this:
$query1 = mysqli_query("query here");
if(!query1){
//display error
} else {
$query2 = mysqli_query("another query here");
if(!query2){
//display error
//rollback the query1
} else {
query3 = mysqli_query("yet again another query");
if(!query3) {
//display error
//rollback the query2
//rollback the query1
} else {
query4 = mysqli_query("eh.. another one");
if(!query4){
//display error
//rollback the query3
//rollback the query2
//rollback the query1
} else {
return success;
}
}
}
}
Is there a best way to rollback the previous query, if the next one fails?
Otherwise I'm gonna have the first 2 query successfull, which edited the database, but the 3° failed, so 3° and 4° didn't edit the dabatase, with the result of having it corrupted.
I thought about something like:
...
$query2 = mysqli_query("another query here");
if(!query2){
//display error
$rollback = mysqli_query("query to rollback query1");
} else {
query3 = mysqli_query("yet again another query");
if(!query3) {
//display error
$rollback = mysqli_query("query to rollback query2");
$rollback = mysqli_query("query to rollback query1");
} else {
...
But the above method grants even more chances to fail more queries.
Is there any other more effective methods?
This is how i would do it with mysqli:
Configure mysqli (somewehere at the begining of your application) to throw exceptions when a query fails.
mysqli_report(MYSQLI_REPORT_STRICT);
This way you will not need all the if .. elseif .. else.
$connection->begin_transaction();
try {
$result1 = $connection->query("query 1");
// do something with $result1
$result2 = $connection->query("query 2");
// do something with $result2
$result3 = $connection->query("query 3");
// do something with $result3
// you will not get here if any of the queries fails
$connection->commit();
} catch (Exception $e) {
// if any of the queries fails, the following code will be executed
$connection->rollback(); // roll back everything to the point of begin_transaction()
// do other stuff to handle the error
}
Update
Usually the user don't care about, why his action failed. If a query fails, it's never the users fault. It's either the fault of the developer or of the environment. So there shouldn't be a reason to render an error message depending on which query failed.
Note that if the users intput is the source of the failed query, then
you didn't validate the input properly
your queries are not injection safe (If the input can cause an SQL error it can also be used to compromise your DB.)
However - I don't say there can't be reasons - I just don't know any. So if you want your error message depend on which query failed, you can do the following:
$error = null;
$connection->begin_transaction();
try {
try {
$result1 = $connection->query("query 1");
} catch (Exception $e) {
$error = 'query 1 failed';
throw $e;
}
// do something with $result1
try {
$result2 = $connection->query("query 2");
} catch (Exception $e) {
$error = 'query 2 failed';
throw $e;
}
// do something with $result2
// execute more queries the same way
$connection->commit();
} catch (Exception $e) {
$connection->rollback();
// use $error to find out which query failed
// do other stuff to handle the error
}

Get the mysql data

I am trying to get a mysql data from the table, here -
try
{
$stmt = $user->prepare("SELECT status FROM users");
$result=$stmt->fetch(PDO::FETCH_ASSOC);
if($result['status'] != "Y")
{
$error[] = "Some error warning!";
}
else
{
// Some php codes
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
Here user is a class where prepare is db connection mysql prepare function. The error always prints - "Array!". I am new to php. Any help will be appreciated.
EDIT: I have managed to solve the problem.
You forgot the call of PDOStatement::execute(). See php.net for some examples.
Have you already tried this?
try
{
$stmt = $user->prepare("SELECT status FROM users");
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($result['status'] != "Y")
{
$error[] = "Some error warning!";
}
else
{
// Some php codes
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
Regarding the Array! output: Did you post the whole code of your script? Were do you try to print the array $error?

PHP rollback method has failed

I have tried this piece of code and unfortunately rollback method failed!
Thank in advance!!
$bash = new mysqli('localhost', 'root', '','dbastegoi');
$bash->autocommit(FALSE);
echo 'timologio';
$r =$bash->query("INSERT INTO tbparastatika (strArithmos, fkERGO, strPROMITH, sngCOST, intTYPOS, intDRASH) VALUES ('1','1001','123123123',800138,1,1)");
//ΕΙΣΑΓΩΓΗ ΤΙΜΟΛΟΓΙΟΥ
$i = $bash->insert_id;
ECHO PHP_EOL;
echo 'dapanh';
try {
$r =$bash->query("INSERT INTO tbdapanes_stegash (idPARASTATnIKO, sngCOST, fkDIAMERISMA, intMONTH) VALUES ($i,100,1,1)");
echo $r;
} catch (Exception $e) {
echo 'error2';
}
$bash->commit();
$bash->rollback();
//$SYNDESH->commit();
//$SYNDESH->rollback();
$bash->close();
You can not make a commit first and then a roolback. You have to make a commit if your query runs without error or make a rollback if you get an error:
try {
$r =$bash->query("INSERT INTO tbdapanes_stegash (idPARASTATnIKO, sngCOST, fkDIAMERISMA, intMONTH) VALUES ($i,100,1,1)");
echo $r;
$bash->commit();
} catch (Exception $e) {
echo 'error2';
$bash->rollback();
}

Yii how to check if query execution failed

I M Using YII to develop web application
i want to check if query executed successfully or not
$data = Yii::app()->db->createCommand($SQL);
$result = $data->queryAll();
if(count($result) == 0)
{
throw new SoapFault('Sender', 'Unable to get display information.');
}
if code will execute if select query return no result-set. but i want to check if query executed successfully or not. based on that i want to throw exception. then if query executed successfully and returned no result-set then some other exception.
how to do this ? any suggestions ?
try {
$result = $data->queryAll();
} catch (Exception $ex) {
echo 'Query failed', $ex->getMessage();
}
try
{
$result = Yii::app()->db->createCommand($sqlQuery)->execute();
echo 'success';
}
catch (Exception $e)
{
echo 'fail';
}

How to Conditionally Retrieve Rows from the Database in PHP?

Ok, I have a database full of values with one field value for prospects and another for clients...
I'd like to retrieve only the clients information...
How do I write the function???
UPDATE
Here is the script I tried to write:
<?php
try {
$sql = "SELECT * FROM clients" // WHERE history" or die(mysql_error());
foreach ($dbh->query($sql) as $row) {
$row['history'] = $value;
if ($value == 'clients'){
echo "1212";
} else {
echo "Failed";
return;
}
}
$dbh = null;
} catch (PDOException $e) {
echo "Failed: " . $e->getMessage();
$dbh->rollback();
}
?>
There's no reason to do a rollback here, especially since you haven't started a transaction, and this is just a SELECT, so there's nothing to rollback ... I'm also not sure why you're nulling out $dbh. It's possible to reuse $dbh for other queries, or throughout your application...
Also, your select statement should reflect what data you actually need. If all you need is history, then SELECT history FROM clients[...] is best.
<?php
try {
$sql = "SELECT * FROM clients WHERE history = 'clients'";
$query = $dbh->prepare($sql);
$query->execute();
while($row = $query->fetch())
{
if($row['history'] == 'clients'){
echo '1212';
}
}
} catch (PDOException $e) {
echo "Failed: " . $e->getMessage();
}
?>
Based on your sample script this would do the same but it would place the conditional operator in the query at the database layer instead of within the script at the application layer:
<?php
try {
$sql = "SELECT * FROM clients WHERE history = 'clients'" // WHERE history" or die(mysql_error());
foreach ($dbh->query($sql) as $row) {
echo "1212";
}
$dbh = null;
} catch (PDOException $e) {
echo "Failed: " . $e->getMessage();
$dbh->rollback();
}
?>
Of course, it obviously won't reflect non-client rows like your sample did, but from what I could understand of your question this was what you actually wanted to have happen.

Categories