php + mysql still commiting - php

I have 3 mysql queries that I execute from php, 1 is successful and 2 are not. I have however set a commit and rollback. When I do a var_dump on the the commit it returns true, the query that is successful inserts the value in the db instead of rolling back.
//connection is established
function __construct() {
$this->error['State']=0;
$this->error['Msg']="";
try {
$db_con=mysqli_connect($this->server, $this->dbuname, $this->dbpassw, $this->database);
$this->db_connection=$db_con;
mysqli_autocommit($db_con,FALSE);
mysqli_begin_transaction($this->db_connection);
}
catch (Exception $e) {
$this->setError("Error: Please try again");
}
}
//query and commit
public function result($sql) {
try {
$result=mysqli_query($this->db_connection,$sql);
if($result) {
$this->result=$result;
}else {
$this->setError("Error: Please try again");
}
}
catch (Exception $e) {
$this->setError("Error: Please try again");
}
}//end of result function
public function commit() {
$mysqli=$this->db_connection;
$c=mysqli_commit($mysqli);
if (!$c) {
$this->setError("Error: Please try again");
mysqli_rollback($mysqli);
}else{
return 1;
}
}
//query
public function make($i){
$sql="INSERT INTO t1(tcol1, tcol2, tcol3) VALUES ";
...
$this->commit();
$this->close_conn();
Thanks

The issue was that the tables were isam and the database was innoDB. When I changed the tables to innoDB it started working.

If you tell it to commit it will commit. It won't roll back just because there was an error in one of the statements. You have to check for errors each time you perform a query and then rollback if there is an error. Or just check at the end before committing:
public function commit() {
$mysqli=$this->db_connection;
if ($this->error['State'] === 0) {
$this->setError("Error: Please try again");
mysqli_rollback($mysqli);
} else {
$c = mysqli_commit($mysqli);
if ($c) return 1;
}
}

Related

php auto commit or begin transaction are not working as expected [duplicate]

I have 3 mysql queries that I execute from php, 1 is successful and 2 are not. I have however set a commit and rollback. When I do a var_dump on the the commit it returns true, the query that is successful inserts the value in the db instead of rolling back.
//connection is established
function __construct() {
$this->error['State']=0;
$this->error['Msg']="";
try {
$db_con=mysqli_connect($this->server, $this->dbuname, $this->dbpassw, $this->database);
$this->db_connection=$db_con;
mysqli_autocommit($db_con,FALSE);
mysqli_begin_transaction($this->db_connection);
}
catch (Exception $e) {
$this->setError("Error: Please try again");
}
}
//query and commit
public function result($sql) {
try {
$result=mysqli_query($this->db_connection,$sql);
if($result) {
$this->result=$result;
}else {
$this->setError("Error: Please try again");
}
}
catch (Exception $e) {
$this->setError("Error: Please try again");
}
}//end of result function
public function commit() {
$mysqli=$this->db_connection;
$c=mysqli_commit($mysqli);
if (!$c) {
$this->setError("Error: Please try again");
mysqli_rollback($mysqli);
}else{
return 1;
}
}
//query
public function make($i){
$sql="INSERT INTO t1(tcol1, tcol2, tcol3) VALUES ";
...
$this->commit();
$this->close_conn();
Thanks
The issue was that the tables were isam and the database was innoDB. When I changed the tables to innoDB it started working.
If you tell it to commit it will commit. It won't roll back just because there was an error in one of the statements. You have to check for errors each time you perform a query and then rollback if there is an error. Or just check at the end before committing:
public function commit() {
$mysqli=$this->db_connection;
if ($this->error['State'] === 0) {
$this->setError("Error: Please try again");
mysqli_rollback($mysqli);
} else {
$c = mysqli_commit($mysqli);
if ($c) return 1;
}
}

Check if a query was successful laravel

I define a query to delete a table in database. After that i want to show a message that the query was run successfully. How can I check it with an if statement?
$query = DB::table('user_users')->delete();
return view('datenbank');
When you use delete with the query builder it will return the number of affected rows.
Your if statement would just need to look something like:
$query = DB::table('user_users')->delete();
if ($query) {
//query successful
}
If you want to be more explicit you could do if ($query > 0) {}
If anything goes wrong with the query (an error) it will throw an Exception which will mean that no rows have been affected.
Personally, I think the best solution is to use an if statement like this.
your code
$query = DB::table('user_users')->delete();
return view('datenbank');
Soluction
$query = DB::table('user_users')->delete();
// check data deleted or not
if ($query > 0) {
return response()->json('202 Accepted', 202);
} else {
return response()->json('404 Not Found', 404);
}
If the query did not execute successfully, Laravel would normally throw an error. But if you want to be really sure, you could query the table right after truncating it to make sure there is no data left.
DB::table('user_users')->delete();
// Test if no records are left in the table
$success = DB::table('user_users')->count() === 0;
return view('datenbank', compact('success'));
I will recommend to use try catch because laravel query throw exception when some error occur...
$queryStatus;
try {
DB::table('user_')->where('column',$something)->delete();
$queryStatus = "Successful";
} catch(Exception $e) {
$queryStatus = "Not success";
}
return view('datenbank')->with('message', $queryStatus);
you can do try catch with DB Transaction
try {
DB::beginTransaction();
// your code
DB::commit();
}catch (Exception $e) {
DB::rollback();
// other actions
}

PDO rollback if affected rows are 0

I create a PDO Database class to manage connections to the db, query's and transactions. I want to execute all the query's in one transaction, so if one throw an error, the others rollback.
Firs i create the update, delete or insert statement to run, and add the query with a function.
public function addQuery($entity)
{
$this->stack[] = $entity;
}
Then i commit all the querys in the array:
public function commit()
{
self::beginTransaction();
try {
foreach ($this->stack as $entity) {
$entity->execute();
}
self::commitTransaction();
return true;
} catch (Exception $e) {
self::rollbackTransaction();
return false;
}
}
This are the functions that i use:
protected function beginTransaction()
{
$this->dbo->beginTransaction();
}
protected function commitTransaction()
{
$this->dbo->commit();
}
protected function rollbackTransaction()
{
$this->dbo->rollBack();
}
I tried making two updates. The firs that will update a row, and the second will affect 0 rows. But my function don't roll back the firs update.
In your code, you catch an error with catch (Exception $e) then execute a rollback.
If you want to consider an SQL statement that affects 0 rows an error then you could do the following:
public function commit()
{
self::beginTransaction();
try {
foreach ($this->stack as $entity) {
$entity->execute();
# If the statement affected 0 rows, then throw an error
# that will trigger a rollback
if ( $entity->rowCount() == 0 ) {
throw new \Exception("0 rows affected.");
}
}
self::commitTransaction();
return true;
} catch (Exception $e) {
self::rollbackTransaction();
return false;
}
}
Cautionary note This could have very unexpected consequences as certain statements (like SELECT) affect 0 rows and then would trigger a ROLLBACK.
Hope this help!

Codeigniter 3: Can't catch database error using try catch block

I'm working on an api, it handles the requests which comes from clients, then gets the response from server(developed using codeigniter 3) and forwards that back to client.
But, in case of any database errors, like duplicate id, or null values, the model class cannot handle that error to display a proper error message. I've tried the try catch block but not succeeded yet.
Here's the model:
public function add() {
try {
$this->db->trans_start(FALSE);
$this->db->insert('users', $preparedData);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
throw new Exception("Database error:");
return false;
}
return TRUE;
} catch (Exception $e) {
log_message('error: ',$e->getMessage());
return;
}
}
One thing to mention, I've set db_debug to FALSE.
Any help would be appreciated.
As for CI 3, below code gets database error code and error message. db_debug is set to FALSE.
public function add() {
try {
$this->db->trans_start(FALSE);
$this->db->insert('users', $preparedData);
$this->db->trans_complete();
// documentation at
// https://www.codeigniter.com/userguide3/database/queries.html#handling-errors
// says; "the error() method will return an array containing its code and message"
$db_error = $this->db->error();
if (!empty($db_error)) {
throw new Exception('Database error! Error Code [' . $db_error['code'] . '] Error: ' . $db_error['message']);
return false; // unreachable retrun statement !!!
}
return TRUE;
} catch (Exception $e) {
// this will not catch DB related errors. But it will include them, because this is more general.
log_message('error: ',$e->getMessage());
return;
}
}
Refer to documentation at https://www.codeigniter.com/userguide3/database/queries.html#handling-errors
saying
If you need to get the last error that has occurred, the error() method will return an array containing its code and message.
It is a bit incomplete in my opinion because it does not show error code and error message in the example code.
I just lost an hour trying to figure out why I can't get the error in my code. You have to check for an error after each statement! Working solution:
function insertUpdate($data) {
$order = $data->order;
$order_products = $data->order_products;
$this->db->trans_start();
$order->user_id = $this->session->user_id;
$error = "OK";
if (!$this->db->insert('_order', $order)) {
$error = $this->db->error()["message"];
}
$id = $this->db->insert_id();
foreach ($order_products as $row) {
$row->order_id = $id;
if (!$this->db->insert('_order_product', $row)) {
$error = $this->db->error()["message"];
break;
}
}
$order_code = substr(md5($id), 0, 6);
if (!$this->db->where('order_id', $id)) {
$error = $this->db->error()["message"];
}
if (!$this->db->update('_order', ["order_code" => $order_code])) {
$error = $this->db->error()["message"];
}
$this->db->trans_complete();
return [
'result' => $error, 'order_code' => $order_code
];
}
Suggestion in above code
Remove line $this->db->trans_complete();
If we see $this->db->error() after completing transaction it will be always empty
Remove semicolon - log_message('error :',$e->getMessage());
return;
public function add()
{
try {
$this->db->trans_start(FALSE);
$this->db->insert('users', $preparedData);
// documentation at
// https://www.codeigniter.com/userguide3/database/queries.html#handling-errors
// says; "the error() method will return an array containing its code and message"
$db_error = $this->db->error();
if (!empty($db_error)) {
throw new Exception('Database error! Error Code [' . $db_error['code'] . '] Error: ' . $db_error['message']);
return false; // unreachable return statement !!!`enter code here`
}
return TRUE;
} catch (Exception $e) {
// this will not catch DB related `enter code here`errors. But it will include them, because this is more general.
log_message('error ',$e->getMessage());
return;
}
}

PDO PHP Update Script not working

I've searched on stackoverflow and other sources but I cant seem to find the issue that is preventing my PHP script from working.
Look at the echo_sql. It produces a healthy update statement which when run updates the database with no problem. Here is a sample:
update waste set waste_name=1 where id =82;
However, when the script is run, it does not apply changes to the database. Here is the script:
if ($_SERVER['REQUEST_METHOD'] == "POST") {
try {
$waste_id = $_POST['waste_id'];
$sql = new db;
$sql->beginTransaction();
$waste_name = $_POST['waste_name'];
$sql->query("update waste set waste_name=:waste_name where id =:waste_id;");
$echo_sql = "update waste set waste_name=$waste_name where id =$waste_id;";
echo $echo_sql;
$sql->bind(':waste_name', $waste_name);
$sql->execute();
$sql->endTransaction();
} catch (Exception $e) {
$sql->rollBack();
echo "Failed: " . $e->getMessage();
}
}
Additional details:
errorCode() = 00000
DB Class:
class db
{
private $stmt;
private $dbc;
public function __construct()
{
$u = "root";
$p = "";
try {
$this->dbc = new PDO('mysql:host=127.0.0.1;dbname=wimsdb', $u, $p);
$this->dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
$e->getMessage();
}
}
public function bind($param, $value, $type = NULL)
{
$this->stmt->bindParam($param, $value, $type);
}
public function beginTransaction()
{
return $this->dbc->beginTransaction();
}
public function rollBack()
{
return $this->dbc->rollBack();
}
public function endTransaction()
{
return $this->dbc->commit();
}
public function cancelTransaction()
{
return $this->dbc->rollBack();
}
public function execute()
{
try {
return $this->stmt->execute();
} catch (PDOException $e) {
return $e->errorInfo;
}
}
public function errorCode()
{
return $this->stmt->errorCode();
}
public function query($query)
{
$this->stmt = $this->dbc->prepare($query);
}
}
Please offer your suggestions on how this could be resolved.
You need to bind the :waste_id too:
$waste_id = $_POST['waste_id'];
$sql = new db;
$sql->beginTransaction();
$waste_name = $_POST['waste_name'];
$sql->query("update waste set waste_name=:waste_name where id =:waste_id;");
$sql->bind(':waste_name', $waste_name);
$sql->bind(':waste_id', $waste_id);
Any time you have an issue like this your error checking should return a meaningful message letting you know where the error is and likely what the error is. You should be able to check your error logs for details and/or output them to your screen during testing.
Add waste_id. To avoid missing parameters, I like putting the parameteers into the execute method. The bind method could be defined anywhere in the code so I had to look through your code and make sure waste_id binding wasn't defined somewhere else. When it's in the execute method, you can quickly see all parameters being defined there...it's also a tad more concise...but both have their uses.
if ($_SERVER['REQUEST_METHOD'] == "POST") {
try {
$waste_id = $_POST['waste_id'];
$sql = new db;
$sql->beginTransaction();
$waste_name = $_POST['waste_name'];
$sql->query("update waste set waste_name=:waste_name where id =:waste_id;");
$echo_sql = "update waste set waste_name=$waste_name where id =$waste_id;";
echo $echo_sql;
//just because I like this syntax for being concise and clear :)
$sql->execute(array(
'waste_id' => $waste_id,
'waste_name' => $waste_name
));
$sql->endTransaction();
} catch (Exception $e) {
$sql->rollBack();
echo "Failed: " . $e->getMessage();
}

Categories