{"id":36650,"date":"2019-10-31T22:12:54","date_gmt":"2019-10-31T19:12:54","guid":{"rendered":"https:\/\/prohoster.info\/blog\/tranzaktsii-v-globalah-intersystems-iris\/"},"modified":"2019-10-31T22:12:54","modified_gmt":"2019-10-31T19:12:54","slug":"tranzaktsii-v-globalah-intersystems-iris","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris","title":{"rendered":"Transactions dans les globales InterSystems IRIS","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Transactions dans les globales InterSystems IRIS\" src=\"\/wp-content\/uploads\/2019\/07\/ee4e58369616511dc213f94158b04e4f.jpg\" style=\"display:block;margin: 0 auto;\" \/>La base de donn\u00e9es InterSystems IRIS prend en charge des structures de donn\u00e9es int\u00e9ressantes : les globals. Il s'agit en r\u00e9alit\u00e9 de cl\u00e9s multi-niveaux avec diverses fonctionnalit\u00e9s suppl\u00e9mentaires telles que des transactions, des fonctions rapides pour naviguer dans les arbres de donn\u00e9es, des verrous et son propre langage, l'ObjectScript.<\/p>\n<p>Pour en savoir plus sur les globals, consultez la s\u00e9rie d'articles \u00ab Globals - des \u00e9p\u00e9es-l\u00e9viers pour le stockage des donn\u00e9es \u00bb :<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/intersystems\/blog\/263791\/\">Arbres. Partie 1<\/a><\/noindex> <br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/intersystems\/blog\/264173\/\">Arbres. Partie 2<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/intersystems\/blog\/268465\/\">Tableaux creux. Partie 3<\/a><\/noindex><\/p>\n<p>Je me suis int\u00e9ress\u00e9 \u00e0 la mani\u00e8re dont les transactions sont mises en \u0153uvre dans les globals et aux sp\u00e9cificit\u00e9s associ\u00e9es. En effet, il s'agit d'une structure de stockage de donn\u00e9es compl\u00e8tement diff\u00e9rente des tables habituelles. Beaucoup plus bas niveau.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nComme il est connu dans la th\u00e9orie des bases de donn\u00e9es relationnelles, une bonne mise en \u0153uvre des transactions doit satisfaire aux exigences suivantes : <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/ACID\">ACID<\/a><\/noindex>:<\/p>\n<p><b>A \u2014 Atomique.<\/b> Tous les changements effectu\u00e9s dans la transaction sont enregistr\u00e9s ou aucun.<\/p>\n<p><b>C \u2014 Coh\u00e9rence.<\/b> Apr\u00e8s la fin de la transaction, l'\u00e9tat logique de la base de donn\u00e9es doit \u00eatre intrins\u00e8quement coh\u00e9rent. Cette exigence concerne en grande partie le programmeur, mais dans le cas des bases de donn\u00e9es SQL, elle concerne \u00e9galement les cl\u00e9s \u00e9trang\u00e8res.<\/p>\n<p><b>I \u2014 Isolation.<\/b> Les transactions ex\u00e9cut\u00e9es simultan\u00e9ment ne doivent pas s'influencer mutuellement.<\/p>\n<p><b>D \u2014 Durabilit\u00e9.<\/b> Apr\u00e8s une transaction r\u00e9ussie, des probl\u00e8mes au niveau inf\u00e9rieur (comme une panne de courant, par exemple) ne doivent pas avoir d'effet sur les donn\u00e9es modifi\u00e9es par la transaction.<\/p>\n<p>Les globals sont des structures de donn\u00e9es non relationnelles. Elles ont \u00e9t\u00e9 con\u00e7ues pour un fonctionnement ultra-rapide sur du mat\u00e9riel tr\u00e8s limit\u00e9. Analysons la mise en \u0153uvre des transactions dans les globals \u00e0 l'aide de <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/_\/intersystems-iris-data-platform\/plans\/222f869e-567c-4928-b572-eb6a29706fbd?tab=instructions\">l'image Docker officielle d'IRIS.<\/a><\/noindex>.<\/p>\n<p>Pour prendre en charge les transactions dans IRIS, on utilise les commandes : <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.intersystems.com\/irislatest\/csp\/docbook\/DocBook.UI.Page.cls?KEY=RCOS_ctstart\">TSTART<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.intersystems.com\/irislatest\/csp\/docbook\/DocBook.UI.Page.cls?KEY=RCOS_ctcommit\">TCOMMIT<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.intersystems.com\/irislatest\/csp\/docbook\/DocBook.UI.Page.cls?KEY=RCOS_ctrollback\">TROLLBACK<\/a><\/noindex>.<\/p>\n<h2>1. Atomicit\u00e9<\/h2>\n<p>\nIl est le plus facile de v\u00e9rifier l'atomicit\u00e9. V\u00e9rifions depuis la console de la base de donn\u00e9es.<\/p>\n<pre><code class=\"bash\">Kill ^a\nTSTART\nSet ^a(1) = 1\nSet ^a(2) = 2\nSet ^a(3) = 3\nTCOMMIT<\/code><\/pre>\n<p>\nEnsuite, faisons une sortie :<\/p>\n<pre><code class=\"bash\">Write ^a(1), \" \", ^a(2), \" \", ^a(3)<\/code><\/pre>\n<p>\nNous obtiendrons :<\/p>\n<pre><code class=\"bash\">1 2 3<\/code><\/pre>\n<p>\nTout est en ordre. L'atomicit\u00e9 est respect\u00e9e : tous les changements ont \u00e9t\u00e9 enregistr\u00e9s.<\/p>\n<p>Compliquons un peu la t\u00e2che, introduisons une erreur et voyons comment la transaction est conserv\u00e9e, partiellement ou pas du tout.<\/p>\n<p>V\u00e9rifions \u00e0 nouveau l'atomicit\u00e9 :<\/p>\n<pre><code class=\"bash\">Kill ^A\nTSTART\nSet ^a(1) = 1\nSet ^a(2) = 2\nSet ^a(3) = 3<\/code><\/pre>\n<p>\nEnsuite, nous forcerons l'arr\u00eat du conteneur, le relancerons et regarderons. <\/p>\n<pre><code class=\"bash\">docker kill my-iris<\/code><\/pre>\n<p>\nCette commande est pratiquement \u00e9quivalente \u00e0 une coupure de courant brutale, car elle envoie un signal d'arr\u00eat imm\u00e9diat du processus SIGKILL.<\/p>\n<p>Une transaction a-t-elle pu \u00eatre enregistr\u00e9e partiellement ?<\/p>\n<pre><code class=\"bash\">WRITE ^a(1), ^a(2), ^a(3)\n^\n ^a(1)<\/code><\/pre>\n<p>\n \u2014 Non, cela ne s'est pas enregistr\u00e9.<\/p>\n<p>Testons la commande de rollback :<\/p>\n<pre><code class=\"bash\">Kill ^A\nTSTART\nSet ^a(1) = 1\nSet ^a(2) = 2\nSet ^a(3) = 3\nTROLLBACK\n\nWRITE ^a(1), ^a(2), ^a(3)\n^\n ^a(1)<\/code><\/pre>\n<p>\nRien non plus ne s'est enregistr\u00e9.<\/p>\n<h2>2. Coh\u00e9rence<\/h2>\n<p>\n\u00c9tant donn\u00e9 que dans les bases de donn\u00e9es, les cl\u00e9s sont \u00e9galement cr\u00e9\u00e9es sur des globaux (rappelons que le global est une structure de stockage de donn\u00e9es de niveau inf\u00e9rieur par rapport \u00e0 une table relationnelle), pour satisfaire \u00e0 l'exigence de coh\u00e9rence, il faut inclure la modification de la cl\u00e9 dans la m\u00eame transaction que la modification du global.<\/p>\n<p>Par exemple, nous avons un global ^person, o\u00f9 nous stockons des personnalit\u00e9s et utilisons comme cl\u00e9 le num\u00e9ro d'identification fiscale.<\/p>\n<pre><code class=\"bash\">^person(1234567, 'firstname') = 'Sergey'\n^person(1234567, 'lastname') = 'Kamenev'\n^person(1234567, 'phone') = '+74995555555\n...<\/code><\/pre>\n<p>\nPour avoir une recherche rapide par nom et pr\u00e9nom, nous avons cr\u00e9\u00e9 la cl\u00e9 ^index.<\/p>\n<pre><code class=\"bash\">^index('Kamenev', 'Sergey', 1234567) = 1<\/code><\/pre>\n<p>\nPour que la base de donn\u00e9es soit coh\u00e9rente, nous devons ajouter la personnalit\u00e9 comme suit :<\/p>\n<pre><code class=\"bash\">TSTART\n^person(1234567, 'firstname') = 'Sergey'\n^person(1234567, 'lastname') = 'Kamenev'\n^person(1234567, 'phone') = '+74995555555\n^index('Kamenev', 'Sergey', 1234567) = 1\nTCOMMIT<\/code><\/pre>\n<p>\nPar cons\u00e9quent, lors de la suppression, nous devons \u00e9galement utiliser une transaction :<\/p>\n<pre><code class=\"bash\">TSTART\nKill ^person(1234567)\nZKill ^index('Kamenev', 'Sergey', 1234567)\nTCOMMIT<\/code><\/pre>\n<p>\nEn d'autres termes, le respect des exigences de coh\u00e9rence repose enti\u00e8rement sur les \u00e9paules du programmeur. Mais quand il s'agit de globaux, c'est normal en raison de leur nature de bas niveau.<\/p>\n<h2>3. Isolation<\/h2>\n<p>\nIci, les choses se compliquent. Plusieurs utilisateurs travaillent simultan\u00e9ment sur la m\u00eame base, modifiant les m\u00eames donn\u00e9es.<\/p>\n<p>La situation est comparable \u00e0 celle o\u00f9 de nombreux utilisateurs travaillent simultan\u00e9ment sur le m\u00eame d\u00e9p\u00f4t de code et essaient de soumettre des modifications dans plusieurs fichiers en m\u00eame temps.<\/p>\n<p>La base de donn\u00e9es doit g\u00e9rer tout cela en temps r\u00e9el. \u00c9tant donn\u00e9 que dans des entreprises s\u00e9rieuses, il existe m\u00eame une personne sp\u00e9ciale responsable du contr\u00f4le des versions (pour le fusionnement des branches, la r\u00e9solution des conflits, etc.), tandis que la base de donn\u00e9es doit faire tout cela en temps r\u00e9el, il devient \u00e9vident que la t\u00e2che est complexe et que la conception de la base de donn\u00e9es et du code qui la maintient est cruciale.<\/p>\n<p>La base de donn\u00e9es ne peut pas comprendre le sens des actions effectu\u00e9es par les utilisateurs afin d'\u00e9viter des conflits lorsqu'ils travaillent sur les m\u00eames donn\u00e9es. Elle ne peut que valider une transaction qui contredit une autre ou les ex\u00e9cuter successivement.<\/p>\n<p>Un autre probl\u00e8me est qu'au cours de l'ex\u00e9cution d'une transaction (avant le commit), l'\u00e9tat de la base peut \u00eatre incoh\u00e9rent. Il est donc souhaitable que d'autres transactions n'aient pas acc\u00e8s \u00e0 cet \u00e9tat incoh\u00e9rent, ce qui est r\u00e9alis\u00e9 dans les bases de donn\u00e9es relationnelles de plusieurs mani\u00e8res : cr\u00e9ation de snapshots, multiversioning des lignes, etc.<\/p>\n<p>Lors de l'ex\u00e9cution parall\u00e8le des transactions, il est important qu'elles ne s'interf\u00e8rent pas mutuellement. C'est ce qu'on appelle la propri\u00e9t\u00e9 d'isolation.<\/p>\n<p>SQL d\u00e9finit 4 niveaux d'isolation :<\/p>\n<ul>\n<li>READ UNCOMMITTED<\/li>\n<li>READ COMMITTED<\/li>\n<li>REPEATABLE READ<\/li>\n<li>SERIALIZABLE<\/li>\n<\/ul>\n<p>\nExaminons chaque niveau s\u00e9par\u00e9ment. Les co\u00fbts de mise en \u0153uvre de chaque niveau augmentent presque de mani\u00e8re exponentielle.<\/p>\n<p><b>READ UNCOMMITTED<\/b> \u2014 c'est le niveau d'isolation le plus bas, mais aussi le plus rapide. Les transactions peuvent lire les modifications apport\u00e9es par d'autres.<\/p>\n<p><b>READ COMMITTED<\/b> \u2014 c'est le niveau d'isolation suivant, qui constitue un compromis. Les transactions ne peuvent pas lire les modifications effectu\u00e9es par d'autres avant le commit, mais peuvent lire toutes les modifications apport\u00e9es apr\u00e8s le commit.<\/p>\n<p>Si nous avons une longue transaction T1, pendant laquelle des commits ont eu lieu dans les transactions T2, T3,\u2026 Tn, qui ont travaill\u00e9 avec les m\u00eames donn\u00e9es que T1, alors lors de la requ\u00eate dans T1, nous obtiendrons \u00e0 chaque fois un r\u00e9sultat diff\u00e9rent. Ce ph\u00e9nom\u00e8ne est appel\u00e9 lecture non r\u00e9p\u00e9table.<\/p>\n<p><b>REPEATABLE READ<\/b> \u2014 \u00e0 ce niveau d'isolation, il n'y a pas de ph\u00e9nom\u00e8ne de lecture non r\u00e9p\u00e9table, car pour chaque requ\u00eate de lecture de donn\u00e9es, un snapshot des donn\u00e9es r\u00e9sultantes est cr\u00e9\u00e9 et, lors d'une r\u00e9utilisation dans cette m\u00eame transaction, les donn\u00e9es du snapshot sont utilis\u00e9es. Cependant, \u00e0 ce niveau d'isolation, il est possible de lire des donn\u00e9es fant\u00f4mes. Cela signifie lire de nouvelles lignes qui ont \u00e9t\u00e9 ajout\u00e9es par des transactions parall\u00e8les valid\u00e9es.<\/p>\n<p><b>SERIALIZABLE<\/b> \u2014 le niveau d'isolation le plus \u00e9lev\u00e9. Il se caract\u00e9rise par le fait que les donn\u00e9es utilis\u00e9es d'une mani\u00e8re ou d'une autre dans la transaction (lecture ou modification) ne deviennent accessibles \u00e0 d'autres transactions qu'apr\u00e8s la fin de la premi\u00e8re transaction.<\/p>\n<p>Commen\u00e7ons par d\u00e9terminer s'il existe une isolation des op\u00e9rations dans la transaction par rapport au flux principal. Ouvrons 2 fen\u00eatres de terminal.<\/p>\n<pre><code class=\"bash\">Kill ^t\n\nWrite ^t(1)\n2<\/code><\/pre>\n<pre><code class=\"bash\">\nTSTART\nSet ^t(1)=2<\/code><\/pre>\n<p>\nIl n'y a pas d'isolation. Un flux voit ce que fait l'autre qui a ouvert la transaction.<\/p>\n<p>Voyons si les transactions de diff\u00e9rents flux voient ce qui se passe \u00e0 l'int\u00e9rieur d'elles. <\/p>\n<p>Ouvrons 2 fen\u00eatres de terminal et ouvrons 2 transactions en parall\u00e8le.<\/p>\n<pre><code class=\"bash\">kill ^t\nTSTART\nWrite ^t(1)\n3<\/code><\/pre>\n<pre><code class=\"bash\">\nTSTART\nSet ^t(1)=3\n<\/code><\/pre>\n<p>\nLes transactions parall\u00e8les se voient mutuellement leurs donn\u00e9es. Ainsi, nous avons obtenu le niveau d'isolation le plus simple mais le plus rapide, READ UNCOMMITTED.<\/p>\n<p>Cela pouvait \u00eatre attendu pour les globaux, pour lesquels la performance a toujours \u00e9t\u00e9 prioritaire. <\/p>\n<p>Que faire si nous avons besoin d'un niveau d'isolation plus \u00e9lev\u00e9 pour les op\u00e9rations sur les globaux ?<\/p>\n<p>Il faut r\u00e9fl\u00e9chir \u00e0 pourquoi il est n\u00e9cessaire d'avoir des niveaux d'isolation et comment ils fonctionnent.<\/p>\n<p>Le niveau d'isolation le plus \u00e9lev\u00e9, SERIALIZE, signifie que le r\u00e9sultat des transactions ex\u00e9cut\u00e9es en parall\u00e8le est \u00e9quivalent \u00e0 leur ex\u00e9cution s\u00e9quentielle, ce qui garantit l'absence de collisions.<\/p>\n<p>Nous pouvons atteindre cela gr\u00e2ce \u00e0 des verrouillages ad\u00e9quats dans ObjectScript, qui ont de nombreuses fa\u00e7ons d'\u00eatre appliqu\u00e9s : on peut faire une verrouillage ordinaire, incr\u00e9mentale ou multiple avec la commande <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.intersystems.com\/latest\/csp\/docbook\/DocBook.UI.Page.cls?KEY=RCOS_clock\">LOCK<\/a><\/noindex>.<\/p>\n<p>Des niveaux d'isolation plus bas repr\u00e9sentent des compromis visant \u00e0 augmenter la vitesse de fonctionnement de la base de donn\u00e9es.<\/p>\n<p>Voyons comment nous pouvons atteindre diff\u00e9rents niveaux d'isolation gr\u00e2ce aux verrouillages.<\/p>\n<p>Cet op\u00e9rateur permet de prendre non seulement des verrouillages exclusifs, n\u00e9cessaires pour modifier des donn\u00e9es, mais aussi des verrouillages partag\u00e9s, qui peuvent \u00eatre pris simultan\u00e9ment par plusieurs flux lorsqu'ils ont besoin de lire des donn\u00e9es qui ne doivent pas \u00eatre modifi\u00e9es par d'autres processus pendant la lecture.<\/p>\n<p>Plus d'informations sur la m\u00e9thode des verrouillages en deux phases en russe et en anglais :<\/p>\n<p>\u2192 <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%94%D0%B2%D1%83%D1%85%D1%84%D0%B0%D0%B7%D0%BD%D0%B0%D1%8F_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0\">Verrouillage en deux phases<\/a><\/noindex><br \/>\n\u2192 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Two-phase_locking\">Two-phase locking<\/a><\/noindex><\/p>\n<p>La difficult\u00e9 r\u00e9side dans le fait qu'au cours de la transaction, l'\u00e9tat de la base de donn\u00e9es peut \u00eatre incoh\u00e9rent, cependant, ces donn\u00e9es incoh\u00e9rentes sont visibles par d'autres processus. Comment \u00e9viter cela ?<\/p>\n<p>Nous cr\u00e9erons \u00e0 l'aide de verrouillages des fen\u00eatres de visibilit\u00e9 dans lesquelles l'\u00e9tat de la base sera coh\u00e9rent. Et toutes les demandes \u00e0 de telles fen\u00eatres de visibilit\u00e9 d'\u00e9tat coh\u00e9rent seront contr\u00f4l\u00e9es par des verrouillages.<\/p>\n<p>Les verrous partag\u00e9s sur les m\u00eames donn\u00e9es sont r\u00e9utilisables : plusieurs processus peuvent les acqu\u00e9rir. Ces verrouillages interdisent \u00e0 d'autres processus de modifier les donn\u00e9es, c'est-\u00e0-dire qu'ils sont utilis\u00e9s pour former des fen\u00eatres d'\u00e9tat coh\u00e9rent de la base de donn\u00e9es.<\/p>\n<p>Les verrous exclusifs sont utilis\u00e9s pour modifier les donn\u00e9es : un tel verrou peut \u00eatre acquis uniquement par un seul processus. Un verrou exclusif peut \u00eatre acquis par :<\/p>\n<ol>\n<li>Tout processus, si les donn\u00e9es sont libres<\/li>\n<li>Uniquement le processus qui a un verrou partag\u00e9 sur ces donn\u00e9es et qui a demand\u00e9 en premier le verrou exclusif.<\/li>\n<\/ol>\n<p>\n<img decoding=\"async\" alt=\"Transactions dans les globales InterSystems IRIS\" src=\"\/wp-content\/uploads\/2019\/07\/bb91ed1268925bc1b9266763ab82646a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPlus la fen\u00eatre de visibilit\u00e9 est \u00e9troite, plus les autres processus doivent attendre longtemps, mais plus l'\u00e9tat de la base de donn\u00e9es peut \u00eatre coh\u00e9rent dans celle-ci.<\/p>\n<p><b>READ_COMMITED<\/b> \u2014 l'essence de ce niveau est que nous voyons uniquement les donn\u00e9es valid\u00e9es d'autres flux. Si les donn\u00e9es dans une autre transaction ne sont pas encore valid\u00e9es, nous voyons leur ancienne version.<\/p>\n<p>Cela nous permet de parall\u00e9liser le travail au lieu d'attendre que le verrou soit lib\u00e9r\u00e9.<\/p>\n<p>Sans astuces sp\u00e9ciales, nous ne pourrons pas voir l'ancienne version des donn\u00e9es dans IRIS, il nous faudra donc nous contenter de verrous.<\/p>\n<p>Par cons\u00e9quent, nous devrons permettre la lecture des donn\u00e9es uniquement lors de moments de coh\u00e9rence \u00e0 l'aide de verrous partag\u00e9s.<\/p>\n<p>Supposons que nous avons une base d'utilisateurs ^person qui se transf\u00e8rent de l'argent.<\/p>\n<p>Le moment du transfert de la personne 123 \u00e0 la personne 242 :<\/p>\n<pre><code class=\"bash\">LOCK +^person(123), +^person(242)\nSet ^person(123, amount) = ^person(123, amount) - amount\nSet ^person(242, amount) = ^person(242, amount) + amount\nLOCK -^person(123), -^person(242)<\/code><\/pre>\n<p>\nLe moment de la requ\u00eate du montant d'argent chez la personne 123 avant le d\u00e9bit doit \u00eatre accompagn\u00e9 d'un verrou exclusif (par d\u00e9faut) :<\/p>\n<pre><code class=\"bash\">LOCK +^person(123)\nWrite ^person(123)<\/code><\/pre>\n<p>\nEt si nous devons afficher l'\u00e9tat du compte dans l'espace personnel, nous pouvons utiliser un verrou partag\u00e9 ou ne pas en utiliser du tout :<\/p>\n<pre><code class=\"bash\">LOCK +^person(123)#\u201dS\u201d\nWrite ^person(123)<\/code><\/pre>\n<p>\nCependant, supposons que les op\u00e9rations de gestion de la base de donn\u00e9es se d\u00e9roulent presque instantan\u00e9ment (je rappelle que les globales sont une structure beaucoup plus basse niveau que la table relationnelle), alors la n\u00e9cessit\u00e9 de ce niveau diminue.<\/p>\n<p><b>REPEATABLE READ<\/b> \u2014 \u00e0 ce niveau d'isolation, il est permis qu'il y ait plusieurs lectures de donn\u00e9es qui peuvent \u00eatre modifi\u00e9es par des transactions parall\u00e8les. <\/p>\n<p>Par cons\u00e9quent, nous devrons \u00e9tablir un verrou partag\u00e9 sur les donn\u00e9es que nous modifions et des verrous exclusifs sur les donn\u00e9es que nous changeons.<\/p>\n<p>L'op\u00e9rateur LOCK permet de sp\u00e9cifier en d\u00e9tail toutes les verrouillages n\u00e9cessaires dans un seul op\u00e9rateur, ce qui peut \u00eatre tr\u00e8s nombreux.<\/p>\n<pre><code class=\"bash\">LOCK +^person(123, amount)#\u201dS\u201d\nlire ^person(123, amount)<\/code><\/pre>\n<p>\nd'autres op\u00e9rations (pendant ce temps, des flux parall\u00e8les tentent de modifier ^person(123, amount), mais ne peuvent pas)<\/p>\n<pre><code class=\"bash\">LOCK +^person(123, amount)\nmodifier ^person(123, amount)\nLOCK -^person(123, amount)\n\nlire ^person(123, amount)\nLOCK -^person(123, amount)#\u201dS\u201d<\/code><\/pre>\n<p>\nLors de l'\u00e9num\u00e9ration des verrouillages s\u00e9par\u00e9s par des virgules, ceux-ci sont pris s\u00e9quentiellement, mais si l'on fait ainsi :<\/p>\n<pre><code class=\"bash\">LOCK +(^person(123),^person(242))<\/code><\/pre>\n<p>\nils sont alors pris atomiquement tous en m\u00eame temps.<\/p>\n<p><b>S\u00c9RIALISER<\/b> \u2014 nous devrons d\u00e9finir des verrouillages de mani\u00e8re \u00e0 ce que, finalement, toutes les transactions qui ont des donn\u00e9es communes s'ex\u00e9cutent de mani\u00e8re s\u00e9quentielle. Pour cette approche, la plupart des verrouillages doivent \u00eatre exclusifs et pris aux plus petites r\u00e9gions du global pour des performances optimales.<\/p>\n<p>En ce qui concerne les d\u00e9bits dans le global ^person, seul le niveau d'isolation S\u00c9RIALISER est acceptable, car l'argent doit \u00eatre d\u00e9pens\u00e9 strictement de mani\u00e8re s\u00e9quentielle, sinon il est possible de d\u00e9penser la m\u00eame somme plusieurs fois.<\/p>\n<h2>4. Durabilit\u00e9<\/h2>\n<p>\nJ'ai effectu\u00e9 des tests avec une coupure brutale du conteneur par<\/p>\n<pre><code class=\"bash\">docker kill my-iris<\/code><\/pre>\n<p>\nLa base les a bien support\u00e9s. Aucun probl\u00e8me n'a \u00e9t\u00e9 d\u00e9tect\u00e9.<\/p>\n<h2>Conclusion<\/h2>\n<p>\nPour les globals dans InterSystems IRIS, le support des transactions est en place. Elles sont r\u00e9ellement atomiques et fiables. Cependant, pour garantir la coh\u00e9rence de la base de donn\u00e9es dans les globals, des efforts du programmeur et l'utilisation de transactions sont n\u00e9cessaires, car il n'y a pas de constructions complexes int\u00e9gr\u00e9es comme les cl\u00e9s \u00e9trang\u00e8res.<\/p>\n<p>Le niveau d'isolation des globals sans utilisation de verrouillages est READ UNCOMMITTED, et avec l'utilisation de verrouillages, il peut atteindre jusqu'au niveau S\u00c9RIALISER.<\/p>\n<p>La justesse et la rapidit\u00e9 des transactions sur les globals d\u00e9pendent fortement des comp\u00e9tences du programmeur : plus les verrouillages partag\u00e9s sont largement utilis\u00e9s lors de la lecture, plus le niveau d'isolation est \u00e9lev\u00e9, et plus les verrouillages exclusifs sont \u00e9troitement pris, plus la rapidit\u00e9 est importante.<br \/>\n<br \/>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/461753\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0421\u0423\u0411\u0414 InterSystems IRIS \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u2014 \u0433\u043b\u043e\u0431\u0430\u043b\u044b. \u041f\u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u043a\u043b\u044e\u0447\u0438 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043b\u044e\u0448\u043a\u0430\u043c\u0438 \u0432 \u0432\u0438\u0434\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439, \u0431\u044b\u0441\u0442\u0440\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a \u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430 ObjectScript. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u0433\u043b\u043e\u0431\u0430\u043b\u0430\u0445 \u0432 \u0446\u0438\u043a\u043b\u0435 \u0441\u0442\u0430\u0442\u0435\u0439 \u00ab\u0413\u043b\u043e\u0431\u0430\u043b\u044b \u2014 \u043c\u0435\u0447\u0438-\u043a\u043b\u0430\u0434\u0435\u043d\u0446\u044b \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445\u00bb: \u0414\u0435\u0440\u0435\u0432\u044c\u044f. \u0427\u0430\u0441\u0442\u044c 1 \u0414\u0435\u0440\u0435\u0432\u044c\u044f. \u0427\u0430\u0441\u0442\u044c 2 \u0420\u0430\u0437\u0440\u0435\u0436\u0435\u043d\u043d\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b. \u0427\u0430\u0441\u0442\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":27448,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-36650","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0421\u0423\u0411\u0414 InterSystems IRIS \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u0430\u0445 InterSystems IRIS | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0421\u0423\u0411\u0414 InterSystems IRIS \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:12:54+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:12:54+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Transactions dans les globals InterSystems IRIS | ProHoster","description":"La base de donn\u00e9es InterSystems IRIS prend en charge des structures int\u00e9ressantes.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u0430\u0445 InterSystems IRIS | ProHoster","og:description":"\u0421\u0423\u0411\u0414 InterSystems IRIS \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:12:54+00:00","article:modified_time":"2019-10-31T19:12:54+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"36650","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 04:17:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:41:52","updated":"2026-01-22 04:17:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/36650","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=36650"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/36650\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/27448"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=36650"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=36650"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=36650"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}