Συναλλαγές σε InterSystems IRIS globals

Συναλλαγές σε InterSystems IRIS globalsΤο InterSystems IRIS DBMS υποστηρίζει ενδιαφέρουσες δομές για την αποθήκευση δεδομένων - παγκόσμιων. Ουσιαστικά, πρόκειται για κλειδιά πολλαπλών επιπέδων με διάφορα πρόσθετα καλούδια με τη μορφή συναλλαγών, γρήγορες λειτουργίες για τη διέλευση δέντρων δεδομένων, κλειδαριές και τη δική του γλώσσα ObjectScript.

Διαβάστε περισσότερα για τους παγκόσμιους στη σειρά άρθρων «Τα παγκόσμια είναι σπαθιά θησαυρού για την αποθήκευση δεδομένων»:

Δέντρα. Μέρος 1
Δέντρα. Μέρος 2
Αραιοί πίνακες. Μέρος 3

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

Όπως είναι γνωστό από τη θεωρία των σχεσιακών βάσεων δεδομένων, μια καλή υλοποίηση των συναλλαγών πρέπει να ικανοποιεί τις απαιτήσεις ΟΞΥ:

Α - Ατομική (ατομικότητα). Όλες οι αλλαγές που έγιναν στη συναλλαγή ή καθόλου καταγράφονται.

Γ - Συνέπεια. Μετά την ολοκλήρωση μιας συναλλαγής, η λογική κατάσταση της βάσης δεδομένων πρέπει να είναι εσωτερικά συνεπής. Από πολλές απόψεις αυτή η απαίτηση αφορά τον προγραμματιστή, αλλά στην περίπτωση των βάσεων δεδομένων SQL αφορά και ξένα κλειδιά.

I - Απομόνωση. Οι παράλληλες συναλλαγές δεν πρέπει να επηρεάζουν η μία την άλλη.

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

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

Για την υποστήριξη συναλλαγών στο IRIS, χρησιμοποιούνται οι ακόλουθες εντολές: TSTART, TCOMMIT, TROLLBACK.

1. Ατομικότητα

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

Kill ^a
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TCOMMIT

Στη συνέχεια καταλήγουμε στο συμπέρασμα:

Write ^a(1), “ ”, ^a(2), “ ”, ^a(3)

Παίρνουμε:

1 2 3

Ολα ειναι καλά. Η ατομικότητα διατηρείται: όλες οι αλλαγές καταγράφονται.

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

Ας ελέγξουμε ξανά την ατομικότητα:

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3

Τότε θα σταματήσουμε με δύναμη το κοντέινερ, θα το εκτοξεύσουμε και θα δούμε.

docker kill my-iris

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

Ίσως η συναλλαγή αποθηκεύτηκε μερικώς;

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

- Όχι, δεν έχει επιβιώσει.

Ας δοκιμάσουμε την εντολή επαναφοράς:

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TROLLBACK

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

Ούτε έχει επιβιώσει τίποτα.

2. Συνέπεια

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

Για παράδειγμα, έχουμε ένα παγκόσμιο ^ πρόσωπο, στο οποίο αποθηκεύουμε προσωπικότητες και χρησιμοποιούμε τον ΑΦΜ ως κλειδί.

^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
...

Για να έχουμε μια γρήγορη αναζήτηση με επώνυμο και όνομα, κάναμε το πλήκτρο ^index.

^index(‘Kamenev’, ‘Sergey’, 1234567) = 1

Για να είναι συνεπής η βάση δεδομένων, πρέπει να προσθέσουμε την περσόνα ως εξής:

TSTART
^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
^index(‘Kamenev’, ‘Sergey’, 1234567) = 1
TCOMMIT

Αντίστοιχα, κατά τη διαγραφή πρέπει επίσης να χρησιμοποιήσουμε μια συναλλαγή:

TSTART
Kill ^person(1234567)
ZKill ^index(‘Kamenev’, ‘Sergey’, 1234567)
TCOMMIT

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

3. Απομόνωση

Εδώ αρχίζουν τα άγρια. Πολλοί χρήστες εργάζονται ταυτόχρονα στην ίδια βάση δεδομένων, αλλάζοντας τα ίδια δεδομένα.

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

Η βάση δεδομένων θα πρέπει να τα ταξινομήσει όλα σε πραγματικό χρόνο. Λαμβάνοντας υπόψη ότι σε σοβαρές εταιρείες υπάρχει ακόμη και ένα ειδικό άτομο που είναι υπεύθυνο για τον έλεγχο εκδόσεων (για συγχώνευση υποκαταστημάτων, επίλυση διενέξεων κ.λπ.), και η βάση δεδομένων πρέπει να τα κάνει όλα αυτά σε πραγματικό χρόνο, η πολυπλοκότητα της εργασίας και η ορθότητα των σχεδιασμός βάσης δεδομένων και κώδικας που την εξυπηρετεί.

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

Ένα άλλο πρόβλημα είναι ότι κατά την εκτέλεση μιας συναλλαγής (πριν από μια δέσμευση), η κατάσταση της βάσης δεδομένων μπορεί να είναι ασυνεπής, επομένως είναι επιθυμητό οι άλλες συναλλαγές να μην έχουν πρόσβαση στην ασυνεπή κατάσταση της βάσης δεδομένων, η οποία επιτυγχάνεται σε σχεσιακές βάσεις δεδομένων με πολλούς τρόπους: δημιουργία στιγμιότυπων, σειρές πολλαπλών εκδόσεων κ.λπ.

Κατά την παράλληλη εκτέλεση συναλλαγών, είναι σημαντικό για εμάς να μην παρεμβαίνουν μεταξύ τους. Αυτή είναι η ιδιότητα της απομόνωσης.

Η SQL ορίζει 4 επίπεδα απομόνωσης:

  • ΔΙΑΒΑΣΤΕ ΑΝΗΜΕΡΩΜΕΝΗ
  • ΔΙΑΒΑΣΤΕ ΑΝΑΓΝΩΡΙΣΜΕΝΗ
  • ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΒΑΣΜΑ
  • ΣΕΙΡΑΙΩΣΙΜΟ

Ας δούμε κάθε επίπεδο ξεχωριστά. Το κόστος εφαρμογής κάθε επιπέδου αυξάνεται σχεδόν εκθετικά.

ΔΙΑΒΑΣΤΕ ΑΝΗΜΕΡΩΜΕΝΗ - αυτό είναι το χαμηλότερο επίπεδο απομόνωσης, αλλά ταυτόχρονα και το ταχύτερο. Οι συναλλαγές μπορούν να διαβάσουν τις αλλαγές που γίνονται η μία από την άλλη.

ΔΙΑΒΑΣΤΕ ΑΝΑΓΝΩΡΙΣΜΕΝΗ είναι το επόμενο επίπεδο απομόνωσης, που είναι ένας συμβιβασμός. Οι συναλλαγές δεν μπορούν να διαβάσουν η μία τις αλλαγές της άλλης πριν από τη δέσμευση, αλλά μπορούν να διαβάσουν τυχόν αλλαγές που έγιναν μετά τη δέσμευση.

Εάν έχουμε μια μακρά συναλλαγή T1, κατά την οποία πραγματοποιήθηκαν δεσμεύσεις στις συναλλαγές T2, T3 ... Tn, η οποία λειτούργησε με τα ίδια δεδομένα με την T1, τότε όταν ζητάμε δεδομένα στο T1 θα έχουμε διαφορετικό αποτέλεσμα κάθε φορά. Αυτό το φαινόμενο ονομάζεται μη επαναλαμβανόμενη ανάγνωση.

ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΒΑΣΜΑ — σε αυτό το επίπεδο απομόνωσης δεν έχουμε το φαινόμενο της μη επαναλαμβανόμενης ανάγνωσης, λόγω του ότι για κάθε αίτημα ανάγνωσης δεδομένων δημιουργείται ένα στιγμιότυπο των δεδομένων αποτελέσματος και όταν επαναχρησιμοποιούνται στην ίδια συναλλαγή, τα δεδομένα από το στιγμιότυπο χρησιμοποιείται. Ωστόσο, είναι δυνατή η ανάγνωση φανταστικών δεδομένων σε αυτό το επίπεδο απομόνωσης. Αυτό αναφέρεται στην ανάγνωση νέων σειρών που προστέθηκαν από παράλληλες δεσμευμένες συναλλαγές.

ΣΕΙΡΑΙΩΣΙΜΟ — το υψηλότερο επίπεδο μόνωσης. Χαρακτηρίζεται από το γεγονός ότι τα δεδομένα που χρησιμοποιούνται με οποιονδήποτε τρόπο σε μια συναλλαγή (ανάγνωση ή αλλαγή) γίνονται διαθέσιμα σε άλλες συναλλαγές μόνο μετά την ολοκλήρωση της πρώτης συναλλαγής.

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

Kill ^t

Write ^t(1)
2

TSTART
Set ^t(1)=2

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

Ας δούμε αν οι συναλλαγές διαφορετικών νημάτων βλέπουν τι συμβαίνει μέσα τους.

Ας ανοίξουμε 2 παράθυρα τερματικού και ας ανοίξουμε 2 συναλλαγές παράλληλα.

kill ^t
TSTART
Write ^t(1)
3

TSTART
Set ^t(1)=3

Οι παράλληλες συναλλαγές βλέπουν η μία τα δεδομένα της άλλης. Έτσι, πήραμε το απλούστερο, αλλά και το πιο γρήγορο επίπεδο απομόνωσης, ΔΙΑΒΑΣΤΕ ΑΔΕΣΜΕΥΤΟ.

Κατ' αρχήν, αυτό θα ήταν αναμενόμενο για τους παγκόσμιους, για τους οποίους η απόδοση ήταν πάντα προτεραιότητα.

Τι γίνεται αν χρειαζόμαστε υψηλότερο επίπεδο απομόνωσης στις επιχειρήσεις σε παγκόσμιο επίπεδο;

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

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

Μπορούμε να το κάνουμε αυτό χρησιμοποιώντας έξυπνες κλειδαριές στο ObjectScript, οι οποίες έχουν πολλές διαφορετικές χρήσεις: μπορείτε να κάνετε κανονικό, αυξητικό, πολλαπλό κλείδωμα με την εντολή LOCK.

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

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

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

Περισσότερες πληροφορίες σχετικά με τη μέθοδο αποκλεισμού δύο φάσεων στα ρωσικά και τα αγγλικά:

Μπλοκάρισμα δύο φάσεων
Κλείδωμα δύο φάσεων

Η δυσκολία είναι ότι κατά τη διάρκεια μιας συναλλαγής η κατάσταση της βάσης δεδομένων μπορεί να είναι ασυνεπής, αλλά αυτά τα ασυνεπή δεδομένα είναι ορατά σε άλλες διεργασίες. Πώς να το αποφύγετε αυτό;

Χρησιμοποιώντας κλειδαριές, θα δημιουργήσουμε παράθυρα ορατότητας στα οποία η κατάσταση της βάσης δεδομένων θα είναι συνεπής. Και όλη η πρόσβαση σε τέτοια παράθυρα ορατότητας του συμφωνηθέντος κράτους θα ελέγχεται από κλειδαριές.

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

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

  1. Οποιαδήποτε διαδικασία εάν τα δεδομένα είναι δωρεάν
  2. Μόνο η διαδικασία που έχει κοινόχρηστο κλείδωμα σε αυτά τα δεδομένα και ήταν η πρώτη που ζήτησε αποκλειστικό κλείδωμα.

Συναλλαγές σε InterSystems IRIS globals

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

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

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

Χωρίς ειδικά κόλπα, δεν θα μπορούμε να δούμε την παλιά έκδοση των δεδομένων στο IRIS, οπότε θα πρέπει να αρκεστούμε σε κλειδαριές.

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

Ας υποθέσουμε ότι έχουμε μια βάση χρηστών ^άτομο που μεταφέρει χρήματα ο ένας στον άλλο.

Η στιγμή της μεταφοράς από το άτομο 123 στο άτομο 242:

LOCK +^person(123), +^person(242)
Set ^person(123, amount) = ^person(123, amount) - amount
Set ^person(242, amount) = ^person(242, amount) + amount
LOCK -^person(123), -^person(242)

Η στιγμή της αίτησης του χρηματικού ποσού από το άτομο 123 πριν από τη χρέωση πρέπει να συνοδεύεται από αποκλειστικό μπλοκ (από προεπιλογή):

LOCK +^person(123)
Write ^person(123)

Και αν πρέπει να εμφανίσετε την κατάσταση του λογαριασμού στον προσωπικό σας λογαριασμό, τότε μπορείτε να χρησιμοποιήσετε ένα κοινόχρηστο κλείδωμα ή να μην το χρησιμοποιήσετε καθόλου:

LOCK +^person(123)#”S”
Write ^person(123)

Ωστόσο, αν υποθέσουμε ότι οι λειτουργίες της βάσης δεδομένων εκτελούνται σχεδόν αμέσως (επιτρέψτε μου να σας υπενθυμίσω ότι τα καθολικά είναι μια δομή πολύ χαμηλότερου επιπέδου από έναν σχεσιακό πίνακα), τότε η ανάγκη για αυτό το επίπεδο μειώνεται.

ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΒΑΣΜΑ - Αυτό το επίπεδο απομόνωσης επιτρέπει πολλαπλές αναγνώσεις δεδομένων που μπορούν να τροποποιηθούν από ταυτόχρονες συναλλαγές.

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

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

LOCK +^person(123, amount)#”S”
чтение ^person(123, amount)

άλλες λειτουργίες (αυτή τη στιγμή τα παράλληλα νήματα προσπαθούν να αλλάξουν ^person(123, ποσό), αλλά δεν μπορούν)

LOCK +^person(123, amount)
изменение ^person(123, amount)
LOCK -^person(123, amount)

чтение ^person(123, amount)
LOCK -^person(123, amount)#”S”

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

LOCK +(^person(123),^person(242))

τότε λαμβάνονται ατομικά όλα ταυτόχρονα.

ΣΕΙΡΩΣΕ — θα πρέπει να ρυθμίσουμε κλειδώματα έτσι ώστε τελικά όλες οι συναλλαγές που έχουν κοινά δεδομένα να εκτελούνται διαδοχικά. Για αυτήν την προσέγγιση, οι περισσότερες κλειδαριές θα πρέπει να είναι αποκλειστικές και να λαμβάνονται στις μικρότερες περιοχές του παγκόσμιου για απόδοση.

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

4. Ανθεκτικότητα

Έκανα δοκιμές με σκληρή κοπή του δοχείου χρησιμοποιώντας

docker kill my-iris

Η βάση τους ανέχτηκε καλά. Δεν εντοπίστηκαν προβλήματα.

Συμπέρασμα

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

Το επίπεδο απομόνωσης των παγκόσμιων χωρίς χρήση κλειδαριών είναι ΔΙΑΒΑΣΜΕΝΟ ΜΗ ΔΕΣΜΕΥΣΕΙΣ και όταν χρησιμοποιείτε κλειδαριές μπορεί να διασφαλιστεί μέχρι το επίπεδο ΣΕΙΡΑΙΩΣΕΩΣ.

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

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο