Mysqli begin-commit

Nikako da prokužim ovu funkciju. :confused:
Ako sam dobro skužio, ideja je da osiguramo da se desio kraj transakcije podataka…ako nije bilo kraja, poništit će se sve što se desilo od početka transakcije.

Ali ne kužim zašto ovako jedan jednostavan primjer ne radi, u čemu je fora?

mysqli_autocommit($db, FALSE);

for ($x=0; $x < 10; $x++) 
{ 
$query="INSERT INTO table (value) VALUES ($x)";
mysqli_query($db,$query);

if($x===5)die();
}

mysqli_commit($db);  

Ovaj primjer sam sklepao po nekakvim osnovnim uputama odavde: http://php.net/manual/en/mysqli.commit.php …no očito sam nešto bitno krivo shvatio

Znači sa uvjetom if($x===5)die(); jednostavno forsiram da se commit nikada ne desi…i očekujem naći praznu tablicu. No tamo uredno ostaju upisane vrijednosti 0-5.

Probao sam i bez die() …forsirajući grešku na nivou baze:

mysqli_autocommit($db, FALSE);

for ($x=0; $x < 10; $x++) 
{ 
if($x===5) $x='force fail'; //failat će jer je value type=integer
$query="INSERT INTO table (value) VALUES ($x)";
mysqli_query($db,$query);
}

mysqli_commit($db);  

…rekoh možda begin-comit radi samo kada greška dođe od tamo…no ista stvar, ostaju prvi upisi…

Gdje griješim? Hvala.

Ne kužim se u MySQL, ali recimo da se snalazim u MS SQL-u - no, princip je isti.

Kada se explicitno pokrene transakcija, transakcija ima dva moguća završetka. Jedan je commit, drugi je rollback.

U praksi to izgleda ovako:

  • počinje se transakcija
  • izvršavaju se SQL naredbe i prati se uspješnost (varijabla)
  • na kraju svih izvršavanja se napravi commit ili rollback, ovisno o statusu varijable

Ako sam dobro shvatio, ovo pokrećeš iz PHP-a ili čega već. Najbolje bi bilo sve poslove baze ostaviti bazi - znači napraviti storanu proceduru koja bi obavila posao.

Bit ce da ti fali mysqli_begin_transaction:

<?php
$link = mysqli_connect("127.0.0.1", "root", "", "test");
mysqli_begin_transaction($link);

for ($x=0; $x < 10; $x++)
{
    $query="INSERT INTO test (broj) VALUES ($x)";
    mysqli_query($link, $query);
    if($x===5)die();
}
mysqli_commit($link);

mysqli_close($link);
?>

Tako i ja očekujem da bi trebao biti tijek procesa. I probavao sam restorat bazu i sa rollback i na način da jednostavno ne trigiram commit. (Jer mi iz primjera nikako nije jasno…kako bi točno trebalo ići. Nikako da uhvatim jedan najosnovniji primjer koji mi radi)

Istina, fali u ovom primjeru koji sam dao…ali sam pokušavao i sa tim.
U ovom primjeru imaju begin_transaction: http://php.net/manual/en/mysqli.begin-transaction.php
U ovom pak nemaju http://php.net/manual/en/mysqli.commit.php (Tu počinju da postave autocomit false)

…jednostavno nemam ideju što griješim.

Provjeri mysql engine koji si setovao, posto MyISAM ne podrzava transakcije.

Note:
This function doesn’t work with non transactional table types (like MyISAM or ISAM).

1 Like

Gdje to podešavam? …do čega to ovisi hoće li podržavati ili ne?

Mozes kad kreiras tabelu. Recimo kroz phpMyAdmin imas opciju Storage Engine i kako vidim default je MyISAM pa prebaci to na InnoDB.

1 Like

To je to, radi sada :wink:

Štoviše primjer iz prvog posta radi i ako započnem transakciju sa:

mysqli_begin_transaction($db);

ili sa

mysqli_autocommit($db, FALSE);

…u jednom i drugom slučaju ne moram trigirati rollback. tj. ukoliko nije trigiran commit neće ništa ostati zapisano u bazi…

Nije da trenutno kapiram koja je onda uloga rollback-a…ali nebitno sad…

Nego još jedno pitanjce, bacio sam pogled na usporedbu MyISAM vs InnoDB, čini se ocke benchmark koji je naletio: https://www.percona.com/blog/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/

…no nešto nisam skužio. Ako se promotre malo diagrami, iako se InnoDB pokazuje superiorniji skoro na svakom diagramu, može se primjetiti da njegova krivulja vrlo često ponire, dok MyISAM zadržava stabilnost na većem…

…e to nisam skužio, na čemu većem?
Tu pišu nekakve brojke diagrama 1,4,16,64,128,256 i gore u objašnjenju stoji:

Method of benchmark:

  1. Prepare table with 1,000,000 records (about 350Mb of data on disk)
  2. Run each query for 1, 4, 16, 64, 128, 256 concurrent threads.
  3. For each thread perform a warm-up run (duration 180 sec), and then

Točku dva ne shvaćam što točno znači?

Trebas uraditi ili commit ili rollback kako bi zatvorio transakciju tj. oslobodio resurse i unlock-ovao red u tabeli. U suprotnom ce cekati da se korisnik automatski “oktaci” sa baze i na taj nacin uradi isto ali to moze potrajati i inace je losa praksa jer bespotrebno jede resurse a i blokira pristup podacima drugim korisnicima.

Pod 2 bi trebale biti simultane konekcije ili broj korisnika koji vrte istu stvar.

Aham, ako sam dobro shvatio, izostanak commita je ekvivalent rollbacku ukoliko zanemarimo vremensku os procesa.

Tako je.