Κοινή χρήση τεχνολογίας

Πώς να χειριστείτε την επίλυση διενέξεων για ταυτόχρονες ενημερώσεις δεδομένων στο PostgreSQL;

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

όμορφη διαχωριστική γραμμή

PostgreSQL


Σε ένα περιβάλλον ταυτόχρονης λειτουργίας βάσης δεδομένων, πολλές συναλλαγές που προσπαθούν να ενημερώσουν τα ίδια δεδομένα ταυτόχρονα μπορεί να προκαλέσουν διενέξεις. Η PostgreSQL παρέχει μια σειρά μηχανισμών για τον χειρισμό αυτών των συγκρούσεων ταυτόχρονης ενημέρωσης για τη διασφάλιση της συνέπειας και της ακεραιότητας των δεδομένων.

όμορφη διαχωριστική γραμμή

1. Σενάρια διένεξης ταυτόχρονης ενημέρωσης

Ενδέχεται να προκύψουν διενέξεις ταυτόχρονης ενημέρωσης όταν δύο ή περισσότερες συναλλαγές επιχειρούν να τροποποιήσουν την ίδια σειρά δεδομένων ταυτόχρονα. Τα κοινά σενάρια περιλαμβάνουν:

  1. Τροποποίηση διαφορετικών στηλών της ίδιας σειράς ταυτόχρονα
  2. Ενημερώστε διαφορετικές τιμές της ίδιας στήλης ταυτόχρονα

όμορφη διαχωριστική γραμμή

2. Μηχανισμός ελέγχου συγχρονισμού στην PostgreSQL

Η PostgreSQL χρησιμοποιεί κυρίως MVCC (Multiversion Concurrency Control) για να χειρίζεται ταυτόχρονες συναλλαγές. Το MVCC επιτρέπει σε μια συναλλαγή να διαβάζει μια έκδοση δεδομένων που πληροί τις απαιτήσεις του επιπέδου απομόνωσης χωρίς να κλειδώνει για να μπλοκάρει τις λειτουργίες ανάγνωσης άλλων συναλλαγών. Ωστόσο, ενδέχεται να προκύψουν διενέξεις κατά τη διάρκεια των λειτουργιών εγγραφής.

(1) Μηχανισμός μπλοκαρίσματος

Η PostgreSQL χρησιμοποιεί διάφορους τύπους κλειδαριών για τον έλεγχο της ταυτόχρονης πρόσβασης στα δεδομένα. Οι συνήθεις τύποι κλειδαριάς περιλαμβάνουν:

  1. Κοινόχρηστο κλείδωμα: Επιτρέπει σε άλλες συναλλαγές την απόκτηση κοινόχρηστων κλειδαριών, αλλά αποτρέπει την απόκτηση αποκλειστικών κλειδαριών. Χρησιμοποιείται συνήθως για λειτουργίες ανάγνωσης.
  2. Exclusive Lock: Αποτρέπει άλλες συναλλαγές από την απόκτηση οποιουδήποτε τύπου κλειδώματος, που χρησιμοποιείται συχνά για λειτουργίες εγγραφής.

Η ευαισθησία κλειδώματος μπορεί να είναι σε επίπεδο σειράς (Σειρά-Επίπεδο), σε επίπεδο σελίδας (Σελίδα-Επίπεδο) και σε επίπεδο πίνακα (Επίπεδο πίνακα).

(2) Επίπεδο απομόνωσης συναλλαγών

Η PostgreSQL υποστηρίζει τέσσερα επίπεδα απομόνωσης συναλλαγών:

  1. Διαβάστε το Uncommitted: Αυτό είναι το χαμηλότερο επίπεδο απομόνωσης Μια συναλλαγή μπορεί να διαβάσει μη δεσμευμένες τροποποιήσεις δεδομένων άλλων συναλλαγών, οι οποίες μπορεί να οδηγήσουν σε προβλήματα όπως βρώμικες αναγνώσεις, μη επαναλαμβανόμενες αναγνώσεις και αναγνώσεις φαντασίας.
  2. Διαβάστε δεσμευμένος: Οι συναλλαγές μπορούν να διαβάζουν μόνο δεδομένα που έχουν υποβληθεί, αποφεύγοντας τις βρώμικες αναγνώσεις, αλλά ενδέχεται να εξακολουθούν να υπάρχουν μη επαναλαμβανόμενες αναγνώσεις και φανταστικές αναγνώσεις.
  3. Επαναλαμβανόμενη ανάγνωση: Η ανάγνωση των ίδιων δεδομένων πολλές φορές σε μια συναλλαγή θα έχει το ίδιο αποτέλεσμα, αποφεύγοντας τις μη επαναλαμβανόμενες αναγνώσεις, αλλά μπορεί να προκύψουν φανταστικές αναγνώσεις.
  4. Σειριοποιήσιμο: Το υψηλότερο επίπεδο απομόνωσης, που διασφαλίζει τη σειριακή εκτέλεση των συναλλαγών μέσω αυστηρού ελέγχου ταυτόχρονης χρήσης, αποφεύγοντας τις βρώμικες αναγνώσεις, τις μη επαναλαμβανόμενες αναγνώσεις και τις φανταστικές αναγνώσεις.

όμορφη διαχωριστική γραμμή

3. Λύση σε διενέξεις ταυτόχρονων ενημερώσεων

(1) Μηχανισμός επανάληψης δοκιμής

Μια απλή προσέγγιση είναι να επαναλάβετε τη συναλλαγή όταν προκύψει μια σύγκρουση. Παραδείγματα είναι τα εξής:

DO
$$
DECLARE
    conflict_detected BOOLEAN := FALSE;
BEGIN
    LOOP
        -- 尝试执行更新操作
        UPDATE products SET price = 100 WHERE id = 1;

        -- 检查是否有冲突(例如,通过检查受影响的行数)
        IF NOT FOUND THEN
            conflict_detected := TRUE;
        ELSE
            EXIT;
        END IF;

        -- 若有冲突,等待一段时间并重试
        IF conflict_detected THEN
            PERFORM pg_sleep(1);
        END IF;
    END LOOP;
END;
$$;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Στο παραπάνω παράδειγμα, εάν η λειτουργία ενημέρωσης δεν επηρεάζει καμία σειρά (που υποδεικνύει ότι ενδέχεται να υπάρχει διένεξη), ορίζεται μια σημαία, αναμένει για ένα χρονικό διάστημα και, στη συνέχεια, προσπαθεί ξανά.

(2) Χρησιμοποιήστε αισιόδοξο έλεγχο συγχρονισμού

Ο αισιόδοξος έλεγχος συγχρονισμού προϋποθέτει ότι σπάνια συμβαίνουν συγκρούσεις συγχρονισμού. Σε αυτήν τη μέθοδο, η συναλλαγή δεν κλειδώνει κατά την ενημέρωση των δεδομένων, αλλά ελέγχει εάν τα δεδομένα έχουν τροποποιηθεί από άλλες συναλλαγές κατά τη δέσμευση. Εάν δεν υπάρχουν διενέξεις, η συναλλαγή δεσμεύεται με επιτυχία, εάν υπάρχουν διενέξεις, η συναλλαγή επαναφέρεται και επαναλαμβάνεται όπως απαιτείται.

-- 获取数据的初始版本
SELECT price AS original_price FROM products WHERE id = 1;

-- 进行业务处理和修改
UPDATE products SET price = 100 WHERE id = 1 AND price = original_price;
  • 1
  • 2
  • 3
  • 4
  • 5

Στο παραπάνω παράδειγμα, η λειτουργία ενημέρωσης επιτυγχάνεται μόνο εάν τα δεδομένα δεν έχουν τροποποιηθεί από άλλες συναλλαγές.

(3) Χρησιμοποιήστε απαισιόδοξο έλεγχο συγχρονισμού

Ο απαισιόδοξος έλεγχος συγχρονισμού υποθέτει ότι είναι πιθανό να προκύψουν συγκρούσεις συγχρονισμού και αποκτά τα απαιτούμενα λουκέτα κατά την εκτέλεση της συναλλαγής για να μπλοκάρει άλλες δυνητικά αντικρουόμενες συναλλαγές.

BEGIN;

-- 获取排他锁
LOCK TABLE products IN SHARE ROW EXCLUSIVE MODE;

-- 进行数据更新
UPDATE products SET price = 100 WHERE id = 1;

COMMIT;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(4) Πεδίο έκδοσης εφαρμογής

Προσθέστε ένα πεδίο έκδοσης στον πίνακα για να παρακολουθείτε τις αλλαγές στα δεδομένα.

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    price DECIMAL(10, 2),
    version INT DEFAULT 0
);
  • 1
  • 2
  • 3
  • 4
  • 5

Κατά την ενημέρωση δεδομένων, αυξήστε επίσης το πεδίο έκδοσης:

UPDATE products SET price = 100, version = version + 1 WHERE id = 1 AND version = <expected_version>;
  • 1

Εάν ο αριθμός των σειρών που επηρεάζονται από την ενημέρωση είναι 0, υπάρχει διένεξη επειδή η αναμενόμενη έκδοση δεν συνάδει με την πραγματική έκδοση.

(5) Επίλυση συγκρούσεων με βάση τη χρονική σήμανση

Προσθέστε ένα πεδίο χρονικής σήμανσης σε κάθε σειρά δεδομένων για να καταγράψετε τον τελευταίο χρόνο τροποποίησης των δεδομένων.

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    price DECIMAL(10, 2),
    last_modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  • 1
  • 2
  • 3
  • 4
  • 5

Κατά την ενημέρωση, ενημερώνετε μόνο δεδομένα με χρονική σήμανση παλαιότερη από τη χρονική σήμανση που διαβάζεται από την τρέχουσα συναλλαγή:

UPDATE products SET price = 100 WHERE id = 1 AND last_modified <= <read_timestamp>;
  • 1

όμορφη διαχωριστική γραμμή

4. Θεωρήσεις σε Πρακτικές Εφαρμογές

(1) Αντίκτυπος στην απόδοση

  1. Οι διαφορετικές μέθοδοι επίλυσης συγκρούσεων έχουν διαφορετικές επιπτώσεις στην απόδοση της βάσης δεδομένων. Για παράδειγμα, η χρήση αποκλεισμού μπορεί να προκαλέσει την αναμονή άλλων συναλλαγών, να αυξήσει τον χρόνο αποκλεισμού του συστήματος και, συνεπώς, να επηρεάσει τη συγχρονικότητα. Ο αισιόδοξος έλεγχος ταυτόχρονης απόδοσης αποδίδει καλύτερα όταν συμβαίνουν σπάνια διενέξεις, αλλά όταν συμβαίνουν συχνά συγκρούσεις, μπορεί να οδηγήσει σε μεγάλο αριθμό επαναλήψεων συναλλαγών, αυξάνοντας τον συνολικό χρόνο εκτέλεσης.
  2. Η εφαρμογή πεδίων έκδοσης ή μεθόδων που βασίζονται σε χρονική σήμανση ενδέχεται να απαιτεί επιπλέον χώρο αποθήκευσης για τη διατήρηση των πληροφοριών έκδοσης ή χρονικής σφραγίδας και την εκτέλεση πρόσθετης κρίσης και επεξεργασίας κατά την ενημέρωση.

(2) Προσαρμοστικότητα επιχειρηματικής λογικής

  1. Ορισμένα επιχειρηματικά σενάρια μπορεί να είναι πιο κατάλληλα για μια συγκεκριμένη μέθοδο επίλυσης συγκρούσεων. Για παράδειγμα, εάν η επιχείρηση έχει πολύ υψηλές απαιτήσεις σχετικά με τη συνοχή των δεδομένων και δεν μπορεί να ανεχθεί τυχόν ασυνέπειες, τότε ο απαισιόδοξος έλεγχος ταυτότητος ή το επίπεδο απομόνωσης σειριοποίησης μπορεί να είναι καλύτερη επιλογή.
  2. Ο αισιόδοξος έλεγχος συγχρονισμού μπορεί να είναι πιο κατάλληλος για σενάρια όπου οι συγκρούσεις είναι λιγότερο συχνές και οι απαιτήσεις χρόνου απόκρισης είναι υψηλότερες.

(3) Μοτίβα διανομής και πρόσβασης δεδομένων

  1. Εάν η πρόσβαση στα δεδομένα είναι εξαιρετικά ταυτόχρονη και πολλές συναλλαγές έχουν συχνά πρόσβαση στις ίδιες σειρές δεδομένων ταυτόχρονα, οι μέθοδοι επίλυσης διενέξεων πρέπει να επιλέγονται πιο προσεκτικά για να αποφευχθεί ο υπερβολικός αποκλεισμός και οι διενέξεις.
  2. Για καταστάσεις όπου η κατανομή των δεδομένων είναι σχετικά ομοιόμορφη και η πιθανότητα σύγκρουσης είναι χαμηλή, μπορούν να χρησιμοποιηθούν σχετικά απλές και αποτελεσματικές μέθοδοι, όπως ο αισιόδοξος έλεγχος ταυτόχρονης χρήσης.

όμορφη διαχωριστική γραμμή

5. Παράδειγμα ανάλυσης

Ας υποθέσουμε ότι έχουμε ένα σύστημα διαχείρισης αποθεμάτων για ένα ηλεκτρονικό κατάστημα με α inventory πίνακα για την αποθήκευση ποσοτήτων αποθέματος ειδών.

CREATE TABLE inventory (
    product_id INT PRIMARY KEY,
    quantity INT,
    last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  • 1
  • 2
  • 3
  • 4
  • 5

Τώρα υπάρχουν δύο ταυτόχρονες συναλλαγές:

Συναλλαγή 1:

BEGIN;
SELECT * FROM inventory WHERE product_id = 1;
-- 假设读取到的数量为 10
UPDATE inventory SET quantity = 5 WHERE product_id = 1 AND last_updated <= <read_timestamp>;
COMMIT;
  • 1
  • 2
  • 3
  • 4
  • 5

Συναλλαγή 2:

BEGIN;
SELECT * FROM inventory WHERE product_id = 1;
-- 假设也读取到的数量为 10
UPDATE inventory SET quantity = 8 WHERE product_id = 1 AND last_updated <= <read_timestamp>;
COMMIT;
  • 1
  • 2
  • 3
  • 4
  • 5

Εάν αυτές οι δύο συναλλαγές εκτελούνται σχεδόν ταυτόχρονα, μπορεί να προκύψει σύγκρουση.

Εάν χρησιμοποιούμε επίλυση διενέξεων βάσει χρονικής σήμανσης:

  1. Η συναλλαγή 1 έλαβε την τρέχουσα χρονική σήμανση κατά την ανάγνωση δεδομένων (T1)。
  2. Η συναλλαγή 2 έλαβε μια ελαφρώς μεταγενέστερη χρονική σήμανση κατά την ανάγνωση των δεδομένων (T2)。

Όταν η συναλλαγή 1 επιχειρεί να ενημερώσει, εάν καμία άλλη συναλλαγή δεν έχει τροποποιήσει τα δεδομένα από τότε που τα διάβασε (δηλ. last_updated <= T1), η ενημέρωση είναι επιτυχής.

Όταν η συναλλαγή 2 προσπαθεί να ενημερώσει, εάν διαπιστώσει ότι τα δεδομένα last_updated περισσότερο από τοT2(Δηλώνει ότι τροποποιήθηκε μετά την ανάγνωση της συναλλαγής 2), η ενημέρωση αποτυγχάνει και η συναλλαγή 2 μπορεί να επιλέξει να επαναφέρει και να προσπαθήσει ξανά ή να εκτελέσει άλλη επεξεργασία σύμφωνα με τη λογική της επιχείρησης.


όμορφη διαχωριστική γραμμή

🎉相关推荐

PostgreSQL