slevinkelevra Δημοσ. 30 Σεπτεμβρίου 2017 Δημοσ. 30 Σεπτεμβρίου 2017 Καλησπέρα Δεδομένα Δεν έχω ξαναδουλέψει με transactions στην php, και θέλω να ρωτήσω κάποια πράγματα, για να σιγουρευτώ οτι δεν έχω λάθος λογικη. Που μάλλον έχω. Δουλέυω με PHP/7.2.0beta3, PDO, prepared statements. Θελω να εισαγω εναν χρηστη, μετα, να παρω το id του και να το εισαγω μαζι με καποια αλλα data σε εναν δευτερο πινακα και να του φτιαξω και εναν φακελο, να βαζει τα αρχεια του. Ο κωδικας μου try{ $stmt = $db_connect->prepare('INSERT INTO users (username, email, password) values(?,?,?)'); $stmt->execute([$u, $e, $p]); $lastInsertId = $db_connect->lastInsertId(); $stmt = null; $stmt = $db_connect->prepare('INSERT INTO useroptions (username, username_id, background) values(?,?,?)'); $stmt->execute([$u, $lastInsertId, 'original']); $stmt = null; if(!file_exists("./user/$u")){ mkdir("./user/$u",0755); } echo "Success." $db_connect->commit(); } catch (Exception $e) { $pdo->rollback(); $stmt = null; echo $e->getCode(); } Το πρόβλημα Αν υπάρχει λάθος στο πρωτο insert, τοτε δεν γινετε κανενα insert. Ομως δημιουργει φακελο και εμφανιζει το Success μαζι με τα λαθη. Αν υπάρχει λάθος στο δευτερο insert, δεν εκτελειται το 2ο , αλλα εκτελει το πρωτο επιτυχως. Επισης δημιουργει φακελο και εμφανιζει το Success μαζι με τα λαθη. Η λυση (?) Υποθετω κατι σαν try beginTransaction insert1 commit flag success1=true catch rollback if flag success1=true try beginTransaction insert2 commit flag success2=true catch rollback if flag success1=true && flag success2=true try mkdir catch mkdirException if !mkdirException echo success αλλα τοτε δεν θα εχει νοημα να βαλω transactions, ας βαλω μια σειρα απο πολλα try-catch και if. Τι θελω απο τη ζωη σας Προφανως υλοποιω το transaction λάθος. Θελω αν αποτυχει το insert1 ή το insert2 ή η δημιουργια φακελου, να μην εκτελεστει τιποτα και να γινει rollback. Αλλιως αν δεν αποτυχει τιποτα, να εμφανισει Success. Νομιζα οτι αυτο γινετε αν βαλεις τα παντα μεταξυ του begin Transaction και του commit. Προφανως κανω λαθος. Ποια ειναι η σωστη υλοποιηση? Κατι σαν αυτο που εγραψα παραπανω η κατι αλλο? Ευχαριστω πολυ
mad-proffessor Δημοσ. 30 Σεπτεμβρίου 2017 Δημοσ. 30 Σεπτεμβρίου 2017 Μπορείς να κάνεις εναν επιπλέον ελεγχο στο $stmt αμεσως μετα το execute. if $stmt Your code goes here
slevinkelevra Δημοσ. 30 Σεπτεμβρίου 2017 Μέλος Δημοσ. 30 Σεπτεμβρίου 2017 Αν εκει που λεει που λεει $pdo->rollback(); το αντικαταστησω με το ΣΩΣΤΟ $db_connect->rollback(); μιας και ετσι εχω δηλωσει τη συνδεση στη βαση και ΟΧΙ ως pdo, τοτε ναι, ε , θα δουλέψει. Δευτερο brainfart σε μια βδομαδα. Περισσότερος ύπνος, λιγότερος καφές. Πάντως, to save some face , πριν το ban και ξυλο, να πω οτι, οποιοδηποτε exception, για να λειτουργήσει πρέπει να είναι πριν το commit. Δηλαδή try{ $stmt = $db_connect->prepare('INSERT INTO users (username, email, password) values(?,?,?)'); $stmt/->execute([$u, $e, $p]); $lastInsertId = $db_connect->lastInsertId(); $stmt = null; $stmt = $db_connect->prepare('INSERT INTO useroptions (username, username_id, background) values(?,?,?)'); $stmt->execute([$u, $lastInsertId, 'original']); $stmt = null; if(!file_exists("./user/$u")){ mkdir("./user/$u",0755); } if(!file_exists("./user/$u")){ // just a stupid hack to throw an exception throw new Exception('no dir', 3); } echo "Success"; $db_connect->commit(); //everything is before the commit } catch (Exception $e) { $db_connect->rollback(); echo "something went terribly wrong. please try again later."; } Με το παραπανω, ειτε δε γινει σωστα καποιο απο τα 2 insert, ειτε για καποιο λογο δεν δημιουργησει τον φακελο, θα πεταξει exception και ουτε φακελο θα φτιαξει τελικα, ουτε θα κανει κανενα απο τα insert στη βαση. Αν εβαζα πρωτα το commit και μετα την δημιουργια/ελεγχο φακελου , θα ηταν αργα. Στην περιπτωση που δεν υπηρχαν λαθη στα insert, αλλα στην δημιουργια/ελεγχο φακελου , το exception θα ερχοταν μετα το commit, ενω ηδη ειχε εκτελεσει τα insert. Το error ειναι αρκετα περιγραφικο Fatal error: Uncaught PDOException: There is no active transaction Οποτε, στη πραξη κανει τα insert, σου γεμιζει τους πινακες, αλλα μενεις χωρις φακελο. Παω τωρα να κοιμηθω κανα 10ωρο.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα