PHP, MySQL transakcje

Potrzebujesz pomocy z C, C++, perl, python, itp.
Awatar użytkownika
kodama
Junior Member
Posty: 633
Rejestracja: 23 maja 2010, 22:30
Lokalizacja: Poznań

PHP, MySQL transakcje

Post autor: kodama »

Panowie czy przebywa tutaj ktoś z wiedzą jak w temacie? Próbuję jedną (wydaje mi się, że prostą rzecz) zrobić, a za nic nie chce mi śmigać. Ktoś, coś?
Awatar użytkownika
marcin1982
Moderator
Posty: 1730
Rejestracja: 05 maja 2011, 12:59
Lokalizacja: Zagłębie Dąbrowskie

Re: PHP, MySQL transakcje

Post autor: marcin1982 »

Napisz konkretnie o co chodzi - co chcesz zrobić i co zrobiłeś do tej pory.
Awatar użytkownika
kodama
Junior Member
Posty: 633
Rejestracja: 23 maja 2010, 22:30
Lokalizacja: Poznań

Re: PHP, MySQL transakcje

Post autor: kodama »

Ok, sprawa wydawało by się jest prosta, a ugryźć tego nie umiem (po części pewnie dlatego, że amator jestem ;) ). W skrócie chodzi o to, że wyświetlam na stronie zawartość bazy, niech będzie, że takiej prostej (baza na InnoDB, isolation level SERIALIZABLE):

Kod: Zaznacz cały

+----+-----------+----------+---------+---------------------+
| id | firstname | lastname | email   | reg_date            |
+----+-----------+----------+---------+---------------------+
|  1 | WWW       | DEF      | ABC@DEF | 2017-06-12 16:11:08 |
|  2 | ASD       | ZXC      | AZX@WER | 2017-06-12 14:15:41 |
+----+-----------+----------+---------+---------------------+
Robię to tak:

Kod: Zaznacz cały

<?php
    function db_connect() {
        $dsn = "mysql:host=localhost;dbname=test;charset=utf8";
        $opt = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,

                    ];
        return new PDO($dsn, 'xxxx', 'xxxx', $opt);
    }
    $pdo = db_connect();
    ?>

    <form action="" method="POST">
    <?php
        $sqlA = $pdo->prepare('SELECT * FROM MyGuests');
        $sqlA -> execute();
        while ($row = $sqlA->fetch()) {
        echo "<div>".$row["firstname"]." - ". $row["lastname"] . " - " . $row["email"]." <input type=\"radio\" name=\"selection\" value=\"". $row["id"] ."\" >  </div>\n\n";
        }
    ?>
    <input type="submit" value="Edit">
    </form>

    <?php

    if (isset($_POST["selection"]))                     {
        $id=$_POST["selection"];
        echo "<form action=\"\" method=\"POST\">";
        $sqlB = $pdo->prepare('SELECT * FROM MyGuests WHERE id = ? LIMIT 1 FOR UPDATE');
        $sqlB -> execute([$id]);

        while ($row = $sqlB->fetch()) {

        echo "<input name=\"firstname\" size=\"10\" type=\"text\" style=\"border: 2px solid red\" value=\"".$row["firstname"]."\">";

        echo "<input type=\"hidden\" name=\"change\" value=\"".$row["id"]."\"> <input type=\"submit\" value=\"OK\"> ";

        echo "</form>";
                                        }

                                                        }

 ?>
 
Wyświetlam zawartość, użytkownik klika na rekord, wyświetla się kolejny formularz gdzie może zmienić wartość/wartości.I teraz - chciałem zastosować transakcje, żeby po kliknięciu edycji na danym rekordzie, ten został w bazie zablokowany do czasu wykonania COMMIT albo ROLLBACK. I tego właśnie nie potrafię ugryźć - gdziekolwiek nie wstawię $pdo->beginTransaction(); i później try { ... } catch { ... },to i tak lipa. W jednej przeglądarce odpalam stronkę, klikam na 1 rekord i daję edycję, pojawia mi się drugi formularz. Na drugim komputerze odpalam to samo, postępuję podobnie i mogę sobie bez problemu zmienić dane w tym rekordzie. A chciałbym, żeby tego nie można było zrobić.

Natomiast jak w konsoli mysqla dam

Kod: Zaznacz cały

BEGIN;
SELECT * FROM MyGuests WHERE id=1 FOR UPDATE;
to działa, tak jakbym tego właśnie chciał - czyli próba edycji rekordu przez stronę nie działa. Tzn. czeka 50 sekund na zwolnienie rekordu (albo do momentu aż wydam COMMIT albo ROLLBACK w mysql). Jeżeli ten czas minie to wyświetla komunikat z sekcji catch { ... } . Jestem phpowym amatorem, spędziłem nad tym sporo czasu, a przypuszczam, że sama sprawa jest dość prosta, tylko ja albo czegoś nie widzę, albo gdzieś mam jakiś mały babol, którego nie umiem znaleźć,
ODPOWIEDZ