PHP MySQL update not execute if call twice in short time - php

I'm using CodeIgniter with MySQL. The case is, customer do shop, and pay with account.
Code as follow:
$globallockname = 'MEM_LOCK_ORDER_PAYLOCK';
//lock with memcache add
if (!$this->getGlobalLock($globallockname, 10)){
dexit(array('error'=>true,'msg'=>'get loack failed'));
}
//check if account is enough
$member = $this->admin_model->getItem('member', array('id'=>$this->_member['id']), false);
if ($this->_member['account'] >= $amountpay){]
//pay
$this->admin_model->update('member', "`account` = `account` - ".$amountpay, "`id` = ".$this->_member['id']);
}else{
//unlock
$this->delGlobalLock($globallockname);
dexit(array('error'=>true,'msg'=>'account is short, please recharge'));
}
//unlock
$this->delGlobalLock($globallockname);
When a customer clicks "buy" once, everything goes fine, but if they click "buy" twice in a short time, this script will execute twice, and the first update will not work.
I've checked the return of $db->query, each of them return true.

You are updating the same field twice. So you will get the last update only.
ie the first update is overwritten with second update..
hope this helps...

once buy button is clicked, disable it and show with progressing caption. This will avoid further clicks.

I did a stupid thing, there's nothing wrong with mysql or codeigniter. In my index controller, I go member member info and then set it again, so the memcache lock did not work, the information was overwrite...

Related

Function to revert mysql statement

How can I implement a undo changes function in my php application, so if the user for example added a new member to a group, or deleted item a notification message will appear: The selected item have been deleted, undo delete action(link that trigger the undo function).
The following is a working code:
public function deleteRecord($id) {
$group = $this->query('SET autocommit=0');
$group = $this->query('DELETE FROM `members` WHERE memberID = '.$id.'');
}
public function undo_delete() {
$member = $this->query('rollback');
if($member) {
trigger_error('Undo action has been completed. ', E_USER_NOTICE);
return true;
}
}
The only problem with this code is the transaction has not been submitted, so rollback or log out will undo all the changes that has been done during the user session, I am not sure if this is the best approach to create a redo function, any suggestions?
You will not be able to undo with 2 different requests .Because when you will call the undo . It will undo all delete happened for all the members . To solve it I would suggest -
You create a new table where you keep the information of the deleted record, eg- deleted_members.
When user calls for undo fetch the data from the deleted_members table and insert into original members table.
After successful insert in original table ,remove the data from the delete information table.
I hope this helped.
Transactions do not survive across PHP requests. If a transaction is still open at the end of the first request, it will be implicitly rolled back when the MySQL connection closes at the end of the request. As a result, there is no longer a transaction to roll back when an undo is requested later.
If you want to implement this functionality, it will need to be implemented in application logic.

Make each user vote only once with Session username

I made a simple vote poll it works fine,but i can't make it for each user i mean i can somehow hide if i even manage votepoll to be saved in users info but it's impossible when i tried insert into users it makes a new user with only votePoll declared...everything else is empty,i think it's a wrong way to approach,i can't even mind how to show votepoll whitch user is voteing.
This is my code of vote
<?php
if(isset($_POST['submitme'])){
$submitme=$_POST['submitme'];
$yesOrNo=$_POST['yesOrNo'];
if(!empty($yesOrNo)){
$sqlv=$con->query("INSERT INTO votepoll (yesorno) VALUES ('{$yesOrNo}')");
header('location:index.php');
}
}
?>
Add your "yesorno" row in users,than make query update,don't insert!
if(isset($_POST['submitme'])){
$submitme=$_POST['submitme'];
$yesOrNo=$_POST['yesOrNo'];
if(!empty($yesOrNo)){
$sqlv=mysqli_query($con,"UPDATE users SET yesorno='$yesOrNo' WHERE username='$username'");
}
}
okay so when you click button yesorno is updated in rows as "yes" or "no" ,you should know how user statuses work, if($userStatus==1) and 1 is equal to Admin do so and etc. i'm just giving you direction now just get yesrno from rows and set it equal to variable and if("$userVote!="yes" && $userVote!="no"):
your html cde below and endif;
I just gave you some idea how to get through this problem and gave a direction.

PHP, Redis, lock produkt, until price increase and after that unlock it

i have a problem, i work at moment at a onlinegame and there it is possible for example, to buy a product, if a user buy it for 5$, the price increase and this user is the new owner, after that the next user can buy it from the current owner for 6$...
This happens a lot of times every secound. To avoid that a more than one user buy the product at same time i add a redis flag, for examle:
buyAction($product_id,...){
$lock_id = "buy_".$product_id;
$is_locked = Predis_Interface::get($lock_id);
if($is_locked) {
die();
} else {
Predis_Interface::set($lock_id, true);
}
...
// add it to a worker query...
// if the worker query is finished with this product, it set the lock_id to false
// Predis_Interface::set($lock_id, false)
}
But the problem is, that sometimes more than one user buying the same product for 5$. Therefore both buyers have 5 less $, but only one has the product...
I hope someone can help me with this problem, please.
Thank you Itamar,
your answer helps me to find a solution, i used now:
$lock_id = "buy_".$product_id;
if (!$redis->setnx($lock_id, true)) {
die();
}
this fix the interval between set and read, and it returns only true if it set it successful.
And later on the query worker, i delete it:
$lock_id = "buy_".$product_id;
$redis->del($lock_id)

MySQL query needs an additional page refresh to show UPDATE changes

Why does this not show the changes after submit? The page has to be refreshed AFTER submission to see the changes.
$full_path = 'users/'.$_SESSION['user_id'].'/images/'.$name;
if($query = mysql_query("UPDATE user_info
SET user_image = '$full_path'
WHERE user_id = '".$_SESSION['user_id']."' AND
username = '".$_GET['username']."'
"))
{
if(move_uploaded_file($tmp_name, '/Applications/XAMPP/xamppfiles/htdocs/'.$full_path)) {
echo 'Got it!';
}
}
So, if I upload / click submit, the query is successful, but you can't see the changes until an additional page refresh.
Make sure that your update query is before your select for your data in the execution of the PHP page.
You need to fix your SQL, you are just leaving yourself open for SQL injection, with using $_GET['username'] directly in your SQL query.
Please look at utilizing parameterization, also keep in mind that order counts when you develop these things. TOP -> DOWN.
If you have a display SQL call BEFORE your UPDATE call, then you will have to refresh again to see changes from the UPDATE SQL call.
You should do a GET redirect after POST request anyway.

Problem with UPDATE MySQL

I have a bit of an issue with my code.
I'm making an administrative panel for users to add things to the database. On occasion, they might try to save data without changing it (open a dialog, click save without changing anything). This, of course, will make mysql_affected_rows() return '0' when checking to see if the UPDATE query worked.
Is there another query to make that will always UPDATE regardless of whether the data is the same or not (or can I modify a simple UPDATE query to always update)?
EDIT
This is for users who don't have programming experience. Of course you wouldn't want to update if there's no reason to, but when a user tries to update and it doesn't happen I end up showing a failure message. Rather than there being something wrong, its just it doesn't need to be updated. I need a way to show the user that, instead of a generic 'failure' message. If it failed for another reason, I still need to know.
From the MySQL Documentation:
If you set a column to the value it currently has, MySQL notices this
and does not update it.
Instead of checking mysql_affected_rows, just check to see if the query was successful:
if(!mysql_query("UPDATE ..."))
{
//failure
}
else
{
$verification = mysql_query("SELECT ROW_COUNT() as rows_affected");
$row = mysql_fetch_row($verification);
$rows_affected = $row[0];
if ($rows_affected > 0)
{
//update was performed
}
else
{
//no update was needed
}
}

Categories