חוקי הפורום

כמה INSERT בדיוק באותו רגע - wp


  • תכנות

    שלום וברכה
    זוהי שאלה מדינית
    האם שייך שכמה גולשים ישלחו בקשת בדיקת מידע בדיוק באותו רגע?
    והאם יש איזה נעילה על הטבלה כך שהבעיה לעיל לא אמורה לקרות?

    אבהיר
    אני אמור לעשות כמו חלוקת מקומות (בא נאמר בבית הכנסת)
    המקומות כולם בטבלה.
    ואני מושך אותה לקוד ע"מ לבצע מניפולציה אפשרית כמו מס' מקומות בשולחן לפי כמות האנשים וכו'.
    האם שייך ששני גולשים ביחד ישלחו ביחד בקשה וייוצר קומפליקט?


  • תכנות

    @ש-ב-ח באיזו פלטפורמה?
    בעקרון זה התפקיד של מנוע מסד הנתונים.


  • תכנות

    @WWW
    כתבתי בנושא wp
    כלומר wordpress
    mysqli

    @WWW אמר בכמה INSERT בדיוק באותו רגע - wp:

    בעקרון זה התפקיד של מנוע מסד הנתונים.

    אם זה היה רק הכנסת שורה הייתי מאמין שהמסד אכן לא יתן.
    אבל מה שקורה כאן זה משיכת נתונים ולאחר מכן ע"פ התניות שהקוד יעשה, אני מכניס שורה חדשה.
    אם שני האנשים ימשכו ביחד את הנתונים אז שניהם יקבלו את אותו המקום...


  • תכנות

    @ש-ב-ח אמר בכמה INSERT בדיוק באותו רגע - wp:

    mysqli

    זה לא כתבת.

    @ש-ב-ח אמר בכמה INSERT בדיוק באותו רגע - wp:

    אם זה היה רק הכנסת שורה הייתי מאמין שהמסד אכן לא יתן.
    אבל מה שקורה כאן זה משיכת נתונים ולאחר מכן ע"פ התניות שהקוד יעשה, אני מכניס שורה חדשה.
    אם שני האנשים ימשכו ביחד את הנתונים אז שניהם יקבלו את אותו המקום...

    @dovid כתב לאחרונה בפורום שיש פונקציה מיוחדת ב SQL שיבצע פעולה רק אם הפעולה האחרת התבצעה, לא זוכר איך קוראים לזה.

    אני היה לי סיפור דומה לפני תקופה קצרה שגרם לי לשגיאות חמורות, וסידרתי את זה בקלות.
    היה לי שאילתא במסד נתונים שמחזירה שורה ראשונה בטבלה שהיא בסטטוס 1, והיה מחזיר ללקוח ערך מסוים מהשורה הזאת, ובהמשך משנה את הסטטוס ל 2.

    הבעיה היתה שקרה ו2 ניגשו ביחד וקיבלו אותו שורה, ואז שניהם קיבלו אותו ערך...

    מה שעשיתי זה בשעת עדכון הסטטוס שוב פעם סינון שישנה רק אם הסטטוס כרגע 1, ואם לא שלא ישנה כלום, ואז הייתי מחזיר שגיאה.

    מקווה שהובנתי...


  • תכנות

    @WWW אמר בכמה INSERT בדיוק באותו רגע - wp:

    ואז הייתי מחזיר שגיאה.

    ומה?
    צד הלקוח קיבל שגיאה?!
    מה הוא אשם?! 🙂



  • @ש-ב-ח הבעיה היא לא הSQL
    הבעיה היא הPHP, שמה בהחלט יכול להיות בעיה של ריצה בו זמנית.
    הפתרון לזה הוא נעילה, הקטע שחייב לרוץ "לבד" אתה עוטף עם flock.

    למשל אם יש לך קוד ששורה א' שלו בודקת אם המקום הנבחר פנוי, ב. אם התשובה חיובית מכניסה INSERT למסד, נכנס גולש מס' 1 ומתבצע עבורו שורה א, והתשובה חיובית. לבינתיים יש גולש 2 שגם עבורו מתבצעת שורה א', וגם שמה השורה חיובית. כעת שורה ב' תתבצע עבור שני הגולשים.
    אם שני השורות הללו יהיו בבלוק נעול, אז גולש 2 לא ייכנס לשורה א' עד שגולש 1 יגמור את שורה ב'.

    למה אני כותב שהבעיה בPHP? כי אם תגלגל את האחריות על המסד נתונים, למשל תעשה שהשדה של מס' המקום הוא ייחודי (אסור כפילות), אז ה"דאגה" של הבו זמניות ירדה מכתפיך - המסד נתונים מבצע את הנעילה וממילא מחזיר שגיאה לאחד מהם (מה אכפת לך איזה). אתה בקוד תופס את השגיאה (או לא..) עם catch וכותב למשתמש "אויש, המקום כבר נתפס לבינתיים".


  • תכנות

    @dovid אמר בכמה INSERT בדיוק באותו רגע - wp:

    הקטע שחייב לרוץ "לבד" אתה עוטף עם flock.

    אני מנסה להבין איך מבצעים את זה.
    מה שמופיע בתיעוד שזה עבור קובץ, איך מבצעים את זה על בלוק קוד?


  • תכנות

    @dovid

    את המתכוון לכזה דבר

    <?php
    
        class Locker {
    
            public $filename;
            private $_lock;
    
            public function __construct($filename) {
                $this->filename = $filename;
            }
    
            /**
             * locks relevant file
             */
            public function lock() {
                    touch($this->filename);
                    $this->_lock = fopen($this->filename, 'r');
                    flock($this->_lock, LOCK_EX);
            }
    
            /**
             * unlock above file
             */
            public function unlock() {
                    flock($this->_lock, LOCK_UN);
            }
    
        }
    
        $locker = new Locker('locker.lock');
        echo "Waiting\n";
        $locker->lock();
        echo "Sleeping\n";
        sleep(30);
        echo "Done\n";
        $locker->unlock();
    
    ?>
    

    הועתק מ https://stackoverflow.com/a/30711675/11322208



  • זה מימוש משוכלל, הפשטות היא ככה

    $fp = fopen("/tmp/lock.txt", "r+");
    
    if (flock($fp, LOCK_EX)) { 
        //code or function call
    } else {
        echo "failed to obtain lock";
    }
    
    fclose($fp);
    

    https://stackoverflow.com/questions/15305296/how-to-use-flock-in-php



  • @dovid לא הבנתי דבריך. האם יש עדיפות שהקוד יטפל בנעילה ולא ה-DB?



  • @yossiz אני לא רמזתי כזה דבר, זה מאוד תלוי בסיטואציה.
    אחריות של הDB זה מעולה מכמה סיבות אבל המון פעמים אי אפשר להעביר את האחריות לDB, וגם כשאפשר לפעמים זה לא כ"כ נכון.


  • תכנות

    @dovid אמר בכמה INSERT בדיוק באותו רגע - wp:

    הפשטות היא ככה

    זה אומר שאחד מהם יקבל שגיאה?
    איך אפשר לחסוך את השגיאה?
    אולי עם sleep ואחרי זה נסיון חוזר?

    עריכה: פשוט ניסיתי וראיתי שזה איכן ממתין...
    תודה על הכל @dovid


התחבר כדי לפרסם תגובה
 

בא תתחבר לדף היומי!