Why the whole Table is locking during a MYSQL TRANSCTION? [duplicate] - php

transaction Query
mysqli_begin_transaction($conn);
$sql = "UPDATE foldertable SET trashed = 1 WHERE serverToken = (SELECT serverToken from servertoken where userToken = ? limit 1) and
(folderId = ?
or
RootFolderPath LIKE
CONCAT (
(SELECT RootFolderPath FROM foldertable WHERE serverToken = (SELECT serverToken from servertoken where userToken = ? ) AND folderid = ? limit 1)
,'/'
, ?
,'%'
)
)";
$stmt = mysqli_stmt_init($conn);
mysqli_stmt_prepare($stmt, $sql);
mysqli_stmt_bind_param($stmt, "sisii", $data["userToken"], $id, $data["userToken"], $id, $id);
if (!mysqli_stmt_execute($stmt)) {
echo mysqli_stmt_error($stmt);
$serverError = true;
return;
}
// echo "\n\n affected rows " . mysqli_affected_rows($conn);
if (mysqli_affected_rows($conn) > 0) {
sleep(15);
// Insert into bin folder
$sql = "INSERT INTO binfolder (serverToken , folderId) value ( (SELECT serverToken from servertoken where userToken = ? limit 1) , ?)";
$stmt = mysqli_stmt_init($conn);
mysqli_stmt_prepare($stmt, $sql);
mysqli_stmt_bind_param($stmt, "si", $data["userToken"], $id);
if (!mysqli_stmt_execute($stmt)) {
echo mysqli_stmt_error($stmt);
$serverError = true;
return;
}
if (mysqli_affected_rows($conn) > 0) {
$success = true;
mysqli_commit($conn);
}
}
Insert Query
INSERT INTO foldertable(serverToken) SELECT (123456)
Problem
if execute the insert query after transaction started but the insert does not have to wait for transaction complete . Because the update query on transaction does lock row involved with insert query.
What I wanted
the Insert query will run immediately if it does not contain the same serverToken needed in Insert query.
Thank You in Advance.

Related

prepared statements on loop and rollback if there are errors

I was hoping someone would guide me in the right direction. What I am trying to accomplish is the following:
user uploads a csv file the data is then stored in a multidimensional array $formatted_payments. Then I check the records on the file against the records on the DB. I need to check if the route from the file matches the route on DB if it does for all records then commit all the updates but if there is one mismatch then i need to rollback all the update. I hope this all makes sense. Here is what I did but I haven't tested yet.
Thank you
$conn->autocommit(FALSE);
$route_errors = [];
foreach($formatted_payments as $val){
$sql = "SELECT id, account_no, payment_amount, route_id, payment_date FROM car_payments WHERE payment_date = '".$date."' AND account_no = '".$val['account_no']. "'";
$res = $conn->query($sql);
$data = $res->fetch_object();
if($data){
if($val['amount'] > 0){
if($val['route_id'] != $data->route_id){
$route_errors[] = $val['account_no'];
}else{
$sql = "UPDATE car_payments SET payment_amount = ? charged = ? WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("sss", $val['amount'], 'Si', $data->id);
$stmt->execute();
}
}else{
$sql = "UPDATE car_payments SET payment_amount = ? charged = ?, pending = ? WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ssss", $val['amount'], 'No', 1, $data->id);
$stmt->execute();
}
}
}
if(!empty($route_errors)){
$conn->roll_back();
echo 'The following accounts do not match the route. Records not imported.<br>';
foreach($route_errors as $value){
echo '<li>' . $value . '</li>';
}
}else{
$conn->commit();
}

How to do Looping to Check Duplicate in MySQL with PHP

I want to make for each data exist on databases then do loop up to get unique data.
Here my code:
$id = rand(10000000,99999999);
$check_id = $db->prepare("SELECT * FROM sh_url WHERE sh_id='$id'");
$check_id->execute();
$count_id = $check_id->rowCount();
for ($count_id != 0) {
$lid = $id+1;
}
$shorturl = htmlentities(base_convert($lid,20,36));
$query = $db->prepare("INSERT INTO `sh_url`(`sh_id`) VALUES (:id)");
$query->bindParam(":id", $lid);
$query->execute();
Why don't you use distinct keyword to do this.
SELECT DISTINCT column1, column2, ...
FROM table_name;

sql server update when WHERE exist

I have sql + php query and i need inform user when update fail exmpl:
$sql = "UPDATE db SET
date = GetDate(),
...
...
...
WHERE name = '$name1' and code = '$code' and value1 = '$value1' and value2='$value2'
";
sqlsrv_query( $con, $sql);
And now if php variables values not 100% match values in db update fails but users cant see that. He can check records and try again. I would like inform him when query update nothing.
Like GOB commented, you can use the PHP sqlsrv_rows_affected function to retrieve the number of affected rows. For example:
$stmt = sqlsrv_query( $conn, $sql , $params, $options );
$row_count = sqlsrv_rows_affected( $stmt );
if ($row_count === false)
echo "Error in retrieving row count.";
else
echo $row_count;
Before directly executing update query,check whether condition in update query exists or not. This can be done by selecting count of that condition.
Try below code:
$sql = "select count(*) as count from db WHERE name = '$name1' and code = '$code' and value1 = '$value1' and value2='$value2' ";
while($row = mysqli_fetch_array($sql))
{
$count = $row['count'];
}
if($count == 0)
{
echo 'update will fail';
}
else
{
$sql = "UPDATE db SET
date = GetDate(),
...
...
...
WHERE name = '$name1' and code = '$code' and value1 = '$value1' and value2='$value2'
";
}

PHP checking if username in multiple tables

I am trying to check if a passed in username is in either one of 3 tables. If it is then it exists and will return true, or else it will return false. Currently it just returns true no matter what.
$stmt = $conn->prepare("SELECT * FROM Table1 INNER JOIN Table2 INNER JOIN Table3 WHERE Table1.username = :name OR Table2.username = :name OR Table3.username = :name");
$stmt->bindParam(':name', $_POST["username"] );
$num_rows = $stmt->execute();
if ($num_rows > 0)
{
echo "true";
}
else
{
echo "false";
}
It's way better to use UNION in that case.
$sql = 'SELECT 1 FROM Table1 WHERE username = :name
UNION
SELECT 1 FROM Table2 WHERE username = :name
UNION
SELECT 1 FROM Table3 WHERE username = :name';
$stmt = $conn->prepare($sql);
$stmt->bindParam(':name', $_POST["username"] );
$qry = $stmt->execute();
if ($stmt->rowCount() == 0) {
// no match
} else {
// match
}

Mysqli -> num_rows always returns 1

This seems to always return 1 for $item_result->num_rows; even though there are 0 rows in the DB. However, if an item exists it updates the row correctly. I'm sure something is wrong with my syntax but I'm having a hard time wrapping my head around this mysqli.
$item_query = "SELECT COUNT(*) FROM `rel` WHERE `cart_id` = '".$cartId."' && `id_item` = '".$item_id."'";
$item_result = $mysqli->query($item_query) or die($mysqli->error.__LINE__);
if($item_result->num_rows==1) {
$item_query2 = "SELECT * FROM `rel` WHERE `cart_id` = '".$cartId."' && `id_item` = '".$item_id."'";
$item_result2 = $mysqli->query($item_query2) or die($mysqli->error.__LINE__);
$getOldItems = $item_result2->fetch_array();
$oldQty = $getOldItems['amount'];
$oldNotes = $getOldItems['notes'];
$newQty = $oldQty + $item_quantity;
$newNotes = $oldNotes . $item_notes;
$update_qty = $mysqli->query("UPDATE rel SET amount = '$newQty', notes = '$newNotes' WHERE `cart_id` = '$cartId' && `id_item` = '$item_id'");
if(!$update_qty){
printf("Errormessage: %s\n", $mysqli->error);
}
header('Location: ./ordernew.php');
} else {
$insert_cart_item = $mysqli->query("INSERT INTO rel (`email`, `cart_id`, `id_item`, `amount`, `notes`) VALUES ('$email', '$cartId', '$item_id', '$item_quantity', '$item_notes')");
if(!$insert_cart_item) {
printf("Errormessage: %s\n", $mysqli->error);
}
header('Location: ./ordernew.php');
}
When you do SELECT COUNT(*) there will always be at least one result. Even if its 0.
You will need to fetch the result of the query to get the correct count.

Categories