Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα

 

Δεδομένα

Δεν έχω ξαναδουλέψει με 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. Προφανως κανω λαθος. Ποια ειναι η σωστη υλοποιηση? Κατι σαν αυτο που εγραψα παραπανω η κατι αλλο? 

 

Ευχαριστω πολυ

Δημοσ.

Αν εκει που λεει που λεει 

$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ωρο.

 

 

 

post-228178-0-46908200-1506794519_thumb.png

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...