Juist gebruik van Transactions
Dit is mijn code tot nu toe van één van de vele plekken waar ik Transactions wil gaan gebruiken. De code is een voorbeeld en draait dus niet live, maar het principe wil ik overal gaan toepassen.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
$query="start transaction";
$result = mysql_query($query, $db);
$query_select="SELECT Id, Aantal_soldaten FROM moving_actions WHERE From_user_id='".$my_user_id."' AND Arrivaltime<NOW()";
$query_select = mysql_query($query_select, $db);
if (mysql_num_rows($result_select) > 0){// Als resultaat > 0 is
while($row=mysql_fetch_array($result)){
//ok, er zijn troepen gevonden die aangekomen zijn
$id = $row['Id'];
$aantal_soldaten = $row['Aantal_soldaten'];
//Hier komt de hele berekening die ophaalt hoeveel soldaten de tegenstander heeft, wat de uitslag is, hoeveel soldaten er over blijven en of er grondstoffen zijn geplunderd
//stuur soldaten terug naar huis
if ($overgebleven_soldaten>0){
$query_update="Update moving_actions SET Aantal_soldaten='".$overgebleven_soldaten."' AND Terug_naar_huis='TRUE' AND Aankomsttijd='".$nieuwe_aankomsttijd."' AND Geplunderde_grondstoffen='".$geplunderde_grondstoffen."' WHERE Id='".$id."'";
$query_update = mysql_query($query_update, $db);
}
//Haal geplunderde grondstoffen van aangevallen dorp af:
if ($geplunderde_grondstoffen>0){
$query_update2="Update dorpen SET Grondstoffen=Grondstoffen-'".$geplunderde_grondstoffen."' WHERE Dorp_id='".$aangevallen_dorp_id."'";
$query_update2 = mysql_query($query_update2, $db);
}
}//einde voor while
}
if((!$query_select) || (!$query_update) || (!$query_update2)){
mysql_query("ROLLBACK");
}else{
mysql_query("COMMIT");
}else{
//Geweldig, alle queries zijn gelukt, er kan niks tussengekomen zijn.
//echo "De queries zijn succesvol uitgevoerd";
}
?>
$query="start transaction";
$result = mysql_query($query, $db);
$query_select="SELECT Id, Aantal_soldaten FROM moving_actions WHERE From_user_id='".$my_user_id."' AND Arrivaltime<NOW()";
$query_select = mysql_query($query_select, $db);
if (mysql_num_rows($result_select) > 0){// Als resultaat > 0 is
while($row=mysql_fetch_array($result)){
//ok, er zijn troepen gevonden die aangekomen zijn
$id = $row['Id'];
$aantal_soldaten = $row['Aantal_soldaten'];
//Hier komt de hele berekening die ophaalt hoeveel soldaten de tegenstander heeft, wat de uitslag is, hoeveel soldaten er over blijven en of er grondstoffen zijn geplunderd
//stuur soldaten terug naar huis
if ($overgebleven_soldaten>0){
$query_update="Update moving_actions SET Aantal_soldaten='".$overgebleven_soldaten."' AND Terug_naar_huis='TRUE' AND Aankomsttijd='".$nieuwe_aankomsttijd."' AND Geplunderde_grondstoffen='".$geplunderde_grondstoffen."' WHERE Id='".$id."'";
$query_update = mysql_query($query_update, $db);
}
//Haal geplunderde grondstoffen van aangevallen dorp af:
if ($geplunderde_grondstoffen>0){
$query_update2="Update dorpen SET Grondstoffen=Grondstoffen-'".$geplunderde_grondstoffen."' WHERE Dorp_id='".$aangevallen_dorp_id."'";
$query_update2 = mysql_query($query_update2, $db);
}
}//einde voor while
}
if((!$query_select) || (!$query_update) || (!$query_update2)){
mysql_query("ROLLBACK");
}else{
mysql_query("COMMIT");
}else{
//Geweldig, alle queries zijn gelukt, er kan niks tussengekomen zijn.
//echo "De queries zijn succesvol uitgevoerd";
}
?>
Gewijzigd op 24/05/2011 18:32:02 door Jordy nvt
Gewijzigd op 24/05/2011 18:20:34 door Tikkes C
@Tikkes C, $result_select komt van de query daarboven waar ik per ongeluk een verkeerde variabele heb gebruikt. Zoals ik al zei is het script een voorbeeld, het gaat meer om de toepassing van Transactions.
Het nut van transactions is, dat als je meer database mutaties doet en deze allemaal verwant aan elkaar zijn en allemaal aan een stuk moeten lukken, biedt het een uitkomst. Je kunt het terug rollen door ROLLBACK aan te roepen als er ergens iets fout gaat in je script (syntax en fatale fouten uitgesloten). Uiteraard moet je wel goed controleren of er iets fout gaat.
Nog iets; 2 maal ELSE in een IF structure kan niet, er kan maar een ELSE zijn, misschien dat je ELSEIF bedoeld.
Wat is je storage engine van de tabellen moving_actions en dorpen? Als je MySQL gebruikt met standaard instellingen waarschijnlijk MyIsam en die ondersteund zover ik weet geen transactions. InnoDB bijvoorbeeld wel. Je zult dan de engine moeten aanpassen wat kan met de query:
Maar klopt het wel met die SELECT query? Er wordt ook gezegd dat die verkeerd zijn, maar wat is de reden daarvoor? En wat moet er dan precies gebeuren en veranderen?
Hiermee is het zeer eenvoudig transacties uit te voeren en je hebt gelijk een goede database driver voor de toekomst!
Het lijkt mij niet erg moeilijk, maar het is apart dat er op internet zo weinig over te vinden is...
Met de select query is niks (op evt injectie na). Je zou alleen de START TRANSACTION na de selectquery beter kunnen uitvoeren gezien de select query niet terug gedraait hoeft te worden.
Transactions zijn ook veel sneller!
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
$query_select="SELECT Id, Aantal_soldaten FROM moving_actions WHERE From_user_id='".$my_user_id."' AND Arrivaltime<NOW()";
$query_select = mysql_query($query_select, $db);
if (mysql_num_rows($result_select) > 0){// Als resultaat > 0 is
$query="start transaction";
$result = mysql_query($query, $db);
while($row=mysql_fetch_array($result)){
//ok, er zijn troepen gevonden die aangekomen zijn
$id = $row['Id'];
$aantal_soldaten = $row['Aantal_soldaten'];
//Hier komt de hele berekening die ophaalt hoeveel soldaten de tegenstander heeft, wat de uitslag is, hoeveel soldaten er over blijven en of er grondstoffen zijn geplunderd
//stuur soldaten terug naar huis
if ($overgebleven_soldaten>0){
$query_update="Update moving_actions SET Aantal_soldaten='".$overgebleven_soldaten."' AND Terug_naar_huis='TRUE' AND Aankomsttijd='".$nieuwe_aankomsttijd."' AND Geplunderde_grondstoffen='".$geplunderde_grondstoffen."' WHERE Id='".$id."'";
$query_update = mysql_query($query_update, $db);
}
//Haal geplunderde grondstoffen van aangevallen dorp af:
if ($geplunderde_grondstoffen>0){
$query_update2="Update dorpen SET Grondstoffen=Grondstoffen-'".$geplunderde_grondstoffen."' WHERE Dorp_id='".$aangevallen_dorp_id."'";
$query_update2 = mysql_query($query_update2, $db);
}
}//einde voor while
if((!$query_select) || (!$query_update) || (!$query_update2)){
mysql_query("ROLLBACK");
}else{
mysql_query("COMMIT");
//Geweldig, alle queries zijn gelukt, er kan niks tussengekomen zijn.
//echo "De queries zijn succesvol uitgevoerd";
}
}//script hoeft geen actie uit te voeren, er is namelijk niemand onderweg
?>
$query_select="SELECT Id, Aantal_soldaten FROM moving_actions WHERE From_user_id='".$my_user_id."' AND Arrivaltime<NOW()";
$query_select = mysql_query($query_select, $db);
if (mysql_num_rows($result_select) > 0){// Als resultaat > 0 is
$query="start transaction";
$result = mysql_query($query, $db);
while($row=mysql_fetch_array($result)){
//ok, er zijn troepen gevonden die aangekomen zijn
$id = $row['Id'];
$aantal_soldaten = $row['Aantal_soldaten'];
//Hier komt de hele berekening die ophaalt hoeveel soldaten de tegenstander heeft, wat de uitslag is, hoeveel soldaten er over blijven en of er grondstoffen zijn geplunderd
//stuur soldaten terug naar huis
if ($overgebleven_soldaten>0){
$query_update="Update moving_actions SET Aantal_soldaten='".$overgebleven_soldaten."' AND Terug_naar_huis='TRUE' AND Aankomsttijd='".$nieuwe_aankomsttijd."' AND Geplunderde_grondstoffen='".$geplunderde_grondstoffen."' WHERE Id='".$id."'";
$query_update = mysql_query($query_update, $db);
}
//Haal geplunderde grondstoffen van aangevallen dorp af:
if ($geplunderde_grondstoffen>0){
$query_update2="Update dorpen SET Grondstoffen=Grondstoffen-'".$geplunderde_grondstoffen."' WHERE Dorp_id='".$aangevallen_dorp_id."'";
$query_update2 = mysql_query($query_update2, $db);
}
}//einde voor while
if((!$query_select) || (!$query_update) || (!$query_update2)){
mysql_query("ROLLBACK");
}else{
mysql_query("COMMIT");
//Geweldig, alle queries zijn gelukt, er kan niks tussengekomen zijn.
//echo "De queries zijn succesvol uitgevoerd";
}
}//script hoeft geen actie uit te voeren, er is namelijk niemand onderweg
?>
Nee, het script klopt toch niet. Wat nu als ik selecteer en iemand anders doet dit tegelijk? Dan moet de Select query toch ook in de Transactie? Kan plz iemand helpen want ik snap er niks meer van,
Nog 1 bump, zou iemand mij kunnen helpen want ik kom er niet meer uit, hoeveel ik ook zoek op het internet.
En een select binnen je transactie is zinloos. Je hoort al boven je while loop te controleren of de select query is gelukt, aangezien de while loop daar afhankelijk van is.
Maar wat gaat er precies mis, want uit je verhaal maak ik op dat je geen foutmeldingen krijgt toch?
Gewijzigd op 30/05/2011 10:10:35 door Arjan -
Select query gebruiker 1 geeft aan dat er een leger is aangekomen
Select query gebruiker 2 geef ook aan dat er een leger is aangekomen
Transaction gebruiker 1 wordt gestart
Transactien gebruiker 2 wordt gestart.
Volgensmij gaat het dan fout. Of is het helemaal goed als ik eerst een Select query uitvoer en als de waar de >0 is dat dan de transactie begint? En moet ik dan binnen die transactie nog op dingen controleren? Of klopt mijn script van 4 posts geleden?
En zie mijn opmerking over foutafhandeling om het script beter te laten werken.
Gewijzigd op 30/05/2011 10:52:31 door Arjan -
Zou je dus kunnen zeggen dat onderstaande script helemaal goed werkt en dus juist gebruik maakt van Transactions zonder dat er dubbele acties kunnen gebeuren? (Behalve dan die foutafhandeling)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
$query_select="SELECT Id, Aantal_soldaten FROM moving_actions WHERE From_user_id='".$my_user_id."' AND Arrivaltime<NOW()";
$query_select = mysql_query($query_select, $db);
if (mysql_num_rows($result_select) > 0){// Als resultaat > 0 is
$query="start transaction";
$result = mysql_query($query, $db);
while($row=mysql_fetch_array($result)){
//ok, er zijn troepen gevonden die aangekomen zijn
$id = $row['Id'];
$aantal_soldaten = $row['Aantal_soldaten'];
//Hier komt de hele berekening die ophaalt hoeveel soldaten de tegenstander heeft, wat de uitslag is, hoeveel soldaten er over blijven en of er grondstoffen zijn geplunderd
//stuur soldaten terug naar huis
if ($overgebleven_soldaten>0){
$query_update="Update moving_actions SET Aantal_soldaten='".$overgebleven_soldaten."' AND Terug_naar_huis='TRUE' AND Aankomsttijd='".$nieuwe_aankomsttijd."' AND Geplunderde_grondstoffen='".$geplunderde_grondstoffen."' WHERE Id='".$id."'";
$query_update = mysql_query($query_update, $db);
}
//Haal geplunderde grondstoffen van aangevallen dorp af:
if ($geplunderde_grondstoffen>0){
$query_update2="Update dorpen SET Grondstoffen=Grondstoffen-'".$geplunderde_grondstoffen."' WHERE Dorp_id='".$aangevallen_dorp_id."'";
$query_update2 = mysql_query($query_update2, $db);
}
}//einde voor while
if((!$query_select) || (!$query_update) || (!$query_update2)){
mysql_query("ROLLBACK");
}else{
mysql_query("COMMIT");
//Geweldig, alle queries zijn gelukt, er kan niks tussengekomen zijn.
//echo "De queries zijn succesvol uitgevoerd";
}
}//script hoeft geen actie uit te voeren, er is namelijk niemand onderweg
?>
$query_select="SELECT Id, Aantal_soldaten FROM moving_actions WHERE From_user_id='".$my_user_id."' AND Arrivaltime<NOW()";
$query_select = mysql_query($query_select, $db);
if (mysql_num_rows($result_select) > 0){// Als resultaat > 0 is
$query="start transaction";
$result = mysql_query($query, $db);
while($row=mysql_fetch_array($result)){
//ok, er zijn troepen gevonden die aangekomen zijn
$id = $row['Id'];
$aantal_soldaten = $row['Aantal_soldaten'];
//Hier komt de hele berekening die ophaalt hoeveel soldaten de tegenstander heeft, wat de uitslag is, hoeveel soldaten er over blijven en of er grondstoffen zijn geplunderd
//stuur soldaten terug naar huis
if ($overgebleven_soldaten>0){
$query_update="Update moving_actions SET Aantal_soldaten='".$overgebleven_soldaten."' AND Terug_naar_huis='TRUE' AND Aankomsttijd='".$nieuwe_aankomsttijd."' AND Geplunderde_grondstoffen='".$geplunderde_grondstoffen."' WHERE Id='".$id."'";
$query_update = mysql_query($query_update, $db);
}
//Haal geplunderde grondstoffen van aangevallen dorp af:
if ($geplunderde_grondstoffen>0){
$query_update2="Update dorpen SET Grondstoffen=Grondstoffen-'".$geplunderde_grondstoffen."' WHERE Dorp_id='".$aangevallen_dorp_id."'";
$query_update2 = mysql_query($query_update2, $db);
}
}//einde voor while
if((!$query_select) || (!$query_update) || (!$query_update2)){
mysql_query("ROLLBACK");
}else{
mysql_query("COMMIT");
//Geweldig, alle queries zijn gelukt, er kan niks tussengekomen zijn.
//echo "De queries zijn succesvol uitgevoerd";
}
}//script hoeft geen actie uit te voeren, er is namelijk niemand onderweg
?>
Iemand die het hopelijk kan bevestigen?