У меня есть следующее update of the users table
и selection
который дает мне updated result
сразу после обновления, и мне интересно, если уместно использовать transaction
здесь? Кроме того, если да, то я использую его правильно в codewisely together with prepared statements
?
try {
// connect to the database
require 'connect.php';
// create an update query
$conn->beginTransaction();
$queryUpdate = $conn->prepare("UPDATE users SET userName=:userName, firstName=:firstName,
lastName=:lastName, password=:password, image=:image WHERE userId=:userId");
$queryUpdate->bindParam( ':userId' , $sUserId );
$queryUpdate->bindParam( ':userName' , $sNewUserName );
$queryUpdate->bindParam( ':firstName' , $sNewFirstName );
$queryUpdate->bindParam( ':lastName' , $sNewLastName );
$queryUpdate->bindParam( ':password' , $sNewPassword );
$queryUpdate->bindParam( ':image' , $sNewImagePath );
$bResult = $queryUpdate->execute();
// create another query to get some of the updated values
$querySelect = $conn->prepare("SELECT users.userName, users.firstName, users.lastName, users.image
FROM users WHERE userId=:userId");
$querySelect->bindParam( ':userId' , $sUserId );
// run query
$querySelect->execute();
$ajResult = $querySelect->fetch(PDO::FETCH_ASSOC);
// take each property one by one
$sUserName = $ajResult['userName'];
$sFirstName = $ajResult['firstName'];
$sLastName = $ajResult['lastName'];
$sImagePath = $ajResult['image'];
// i.e. no query has failed, and we can commit the transaction
$conn->commit();
$sjResponse = $bResult ? '{"status":"ok", "userName":"'.$sUserName.'", "firstName":"'.$sFirstName.'",
"lastName":"'.$sLastName.'", "image":"'.$sImagePath.'"}' : '{"status":"error"}';
echo $sjResponse;
} catch (Exception $e) {
// An exception has been thrown
// We must rollback the transaction
echo "ERROR";
$conn->rollback();
}
Если вам просто нужно передать результат обновления, если выполнение обновления преуспело, то передайте обратно значения, которые вы только что использовали в обновлении. В качестве дополнительной проверки вы можете использовать rowCount()
чтобы проверить, что она действительно что-то обновила.
require 'connect.php';
// create an update query
$queryUpdate = $conn->prepare("UPDATE users SET userName=:userName, firstName=:firstName,
lastName=:lastName, password=:password, image=:image WHERE userId=:userId");
$queryUpdate->bindParam( ':userId' , $sUserId );
$queryUpdate->bindParam( ':userName' , $sNewUserName );
$queryUpdate->bindParam( ':firstName' , $sNewFirstName );
$queryUpdate->bindParam( ':lastName' , $sNewLastName );
$queryUpdate->bindParam( ':password' , $sNewPassword );
$queryUpdate->bindParam( ':image' , $sNewImagePath );
$bResult = $queryUpdate->execute();
$sjResponse = ( $bResult && $queryUpdate->rowCount() == 1) ?
'{"status":"ok",
"userName":"'.$sUserName.'",
"firstName":"'.$sNewFirstName.'",
"lastName":"'.$sNewLastName.'",
"image":"'.$sNewImagePath.'"}'
: '{"status":"error"}';
echo $sjResponse;
Что касается транзакций - они более актуальны, когда вы делаете несколько обновлений/вставки/удаления в базу данных. Например, если вы хотите перенести некоторые точки от одного пользователя к другому - вы хотите убедиться, что значение, снятое с пользователя A, попадает пользователю B. Если вы вычтите значение из A, а затем что-то не удалось с обновлением пользователя B, тогда точки могут просто исчезнуть. Используя транзакции, это может отменить оба изменения, и все согласовано.
mysqli->affected_rows
?
rowCount()
в заявлении (обновленный код)
Мне интересно, если уместно использовать транзакцию здесь?
IMO, Нет. У вас есть только одно выражение об обновлении для управления таблицей.
Таким образом, цель объединения нескольких SQL в единую транзакцию также является типом логической группировки всех связанных SQL, и они должны выполняться в одной последовательности. И вы сможете использовать некоторые другие функции, такие как SAVEPOINT
, ROLLBACK
и COMMIT
хотя некоторые из них могут использоваться при выполнении простого запроса (без транзакции).
Я бы предложил прочитать Transactional and Locking Statement