{"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\/pt\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris","title":{"rendered":"Transa\u00e7\u00f5es em globais InterSystems IRIS","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Transa\u00e7\u00f5es em globais InterSystems IRIS\" src=\"\/wp-content\/uploads\/2019\/07\/ee4e58369616511dc213f94158b04e4f.jpg\" style=\"display:block;margin: 0 auto;\" \/>O SGBD InterSystems IRIS suporta estruturas curiosas para armazenamento de dados \u2014 globais. Essencialmente, s\u00e3o chaves em m\u00faltiplos n\u00edveis com diversas funcionalidades adicionais, como transa\u00e7\u00f5es, fun\u00e7\u00f5es r\u00e1pidas para navega\u00e7\u00e3o em \u00e1rvores de dados, bloqueios e sua pr\u00f3pria linguagem ObjectScript.<\/p>\n<p>Saiba mais sobre globais na s\u00e9rie de artigos \"Globais \u2014 espadas m\u00e1gicas para armazenamento de dados\":<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/intersystems\/blog\/263791\/\">\u00c1rvores. Parte 1<\/a><\/noindex> <br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/intersystems\/blog\/264173\/\">\u00c1rvores. Parte 2<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/intersystems\/blog\/268465\/\">Matrizes esparsas. Parte 3<\/a><\/noindex><\/p>\n<p>Fiquei curioso sobre como as transa\u00e7\u00f5es s\u00e3o implementadas em globais, quais s\u00e3o suas particularidades. Afinal, trata-se de uma estrutura totalmente diferente para armazenamento de dados em compara\u00e7\u00e3o com as tabelas habituais. \u00c9 muito mais de baixo n\u00edvel.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nComo \u00e9 sabido na teoria de bancos de dados relacionais, uma boa implementa\u00e7\u00e3o de transa\u00e7\u00f5es deve satisfazer os requisitos <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/ACID\">ACID<\/a><\/noindex>:<\/p>\n<p><b>A \u2014 Atomicidade.<\/b> Todas as altera\u00e7\u00f5es feitas na transa\u00e7\u00e3o s\u00e3o registradas ou nenhuma delas \u00e9.<\/p>\n<p><b>C \u2014 Consist\u00eancia.<\/b> Ap\u00f3s a conclus\u00e3o da transa\u00e7\u00e3o, o estado l\u00f3gico do BD deve ser internamente consistente. Em grande parte, esse requisito diz respeito ao programador, mas, no caso de bancos de dados SQL, tamb\u00e9m se relaciona a chaves externas.<\/p>\n<p><b>I \u2014 Isolamento.<\/b> Transa\u00e7\u00f5es executadas em paralelo n\u00e3o devem influenciar umas \u00e0s outras.<\/p>\n<p><b>D \u2014 Durabilidade.<\/b> Ap\u00f3s a conclus\u00e3o bem-sucedida da transa\u00e7\u00e3o, problemas em n\u00edveis inferiores (como uma falha de energia) n\u00e3o devem afetar os dados alterados pela transa\u00e7\u00e3o.<\/p>\n<p>Globais s\u00e3o estruturas de dados n\u00e3o relacionais. Elas foram criadas para operar em alta velocidade em hardware muito limitado. Vamos examinar a implementa\u00e7\u00e3o de transa\u00e7\u00f5es em globais usando <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/_\/intersystems-iris-data-platform\/plans\/222f869e-567c-4928-b572-eb6a29706fbd?tab=instructions\">a imagem docker oficial do IRIS<\/a><\/noindex>.<\/p>\n<p>Para suportar transa\u00e7\u00f5es no IRIS, s\u00e3o utilizados os comandos: <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. Atomicidade<\/h2>\n<p>\n\u00c9 mais f\u00e1cil verificar a atomicidade. Vamos testar pelo console do banco de dados.<\/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>\nDepois, faremos a seguinte verifica\u00e7\u00e3o:<\/p>\n<pre><code class=\"bash\">Write ^a(1), \u201c \u201d, ^a(2), \u201c \u201d, ^a(3)<\/code><\/pre>\n<p>\nReceberemos:<\/p>\n<pre><code class=\"bash\">1 2 3<\/code><\/pre>\n<p>\nTudo em ordem. Atomicidade cumprida: todas as altera\u00e7\u00f5es foram gravadas.<\/p>\n<p>Vamos complicar a situa\u00e7\u00e3o, introduzindo um erro e vendo como a transa\u00e7\u00e3o ser\u00e1 mantida, parcialmente ou n\u00e3o.<\/p>\n<p>Mais uma vez, vamos verificar a atomicidade:<\/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>\nEm seguida, pararemos o cont\u00eainer for\u00e7osamente, reiniciaremos e veremos. <\/p>\n<pre><code class=\"bash\">docker kill my-iris<\/code><\/pre>\n<p>\nEste comando \u00e9 praticamente equivalente a uma interrup\u00e7\u00e3o for\u00e7ada de energia, pois envia um sinal de parada imediata do processo SIGKILL.<\/p>\n<p>Pode ser que a transa\u00e7\u00e3o tenha sido salva parcialmente?<\/p>\n<pre><code class=\"bash\">WRITE ^a(1), ^a(2), ^a(3)\n^\n ^a(1)<\/code><\/pre>\n<p>\n \u2014 N\u00e3o, n\u00e3o foi salva.<\/p>\n<p>Testaremos o comando de revers\u00e3o:<\/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>\nNada foi salvo tamb\u00e9m.<\/p>\n<h2>2. Consist\u00eancia<\/h2>\n<p>\nComo nas bases de dados globais as chaves tamb\u00e9m s\u00e3o feitas em globais (lembro que global \u00e9 uma estrutura de n\u00edvel inferior para armazenamento de dados, comparado a uma tabela relacional), para atender \u00e0 exig\u00eancia de consist\u00eancia, a modifica\u00e7\u00e3o da chave deve ser inclu\u00edda na mesma transa\u00e7\u00e3o que a modifica\u00e7\u00e3o do global.<\/p>\n<p>Por exemplo, temos o global ^person, onde armazenamos personalidades e usamos o CPF como chave.<\/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>\nPara ter uma busca r\u00e1pida pelo sobrenome e nome, criamos a chave ^index.<\/p>\n<pre><code class=\"bash\">^index('Kamenev', 'Sergey', 1234567) = 1<\/code><\/pre>\n<p>\nPara que o banco esteja consistente, devemos adicionar a personalidade da seguinte forma:<\/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>\nPortanto, ao excluir, tamb\u00e9m devemos usar uma transa\u00e7\u00e3o:<\/p>\n<pre><code class=\"bash\">TSTART\nKill ^person(1234567)\nZKill ^index('Kamenev', 'Sergey', 1234567)\nTCOMMIT<\/code><\/pre>\n<p>\nEm outras palavras, o cumprimento da exig\u00eancia de consist\u00eancia recai completamente sobre os ombros do programador. Mas quando se trata de globais, isso \u00e9 normal, devido \u00e0 sua natureza de n\u00edvel inferior.<\/p>\n<h2>3. Isolamento<\/h2>\n<p>\nAqui come\u00e7am as complica\u00e7\u00f5es. Muitos usu\u00e1rios trabalham simultaneamente em um mesmo banco de dados, alterando os mesmos dados.<\/p>\n<p>A situa\u00e7\u00e3o \u00e9 compar\u00e1vel a muitos usu\u00e1rios trabalhando simultaneamente em um mesmo reposit\u00f3rio de c\u00f3digo e tentando commitar mudan\u00e7as em muitos arquivos ao mesmo tempo.<\/p>\n<p>O banco de dados deve lidar com tudo isso em tempo real. Considerando que em empresas s\u00e9rias h\u00e1 at\u00e9 uma pessoa espec\u00edfica respons\u00e1vel pelo controle de vers\u00f5es (por fus\u00f5es de branches, resolu\u00e7\u00e3o de conflitos etc.), e que o BD deve fazer tudo isso em tempo real, a complexidade da tarefa e a corre\u00e7\u00e3o do design do banco de dados e do c\u00f3digo que o suporta tornam-se evidentes.<\/p>\n<p>O banco de dados n\u00e3o consegue entender o significado das a\u00e7\u00f5es executadas pelos usu\u00e1rios para evitar conflitos ao trabalharem com os mesmos dados. Ele pode apenas desfazer uma transa\u00e7\u00e3o que contradiz outra ou execut\u00e1-las de forma sequencial.<\/p>\n<p>Outro problema \u00e9 que, durante a execu\u00e7\u00e3o da transa\u00e7\u00e3o (antes do commit), o estado do banco pode estar inconsistente, por isso \u00e9 desej\u00e1vel que outras transa\u00e7\u00f5es n\u00e3o tenham acesso a esse estado inconsistente do banco de dados, o que \u00e9 alcan\u00e7ado em bancos de dados relacionais de v\u00e1rias maneiras: cria\u00e7\u00e3o de snapshots, multiversionamento de linhas, etc.<\/p>\n<p>Durante a execu\u00e7\u00e3o paralela de transa\u00e7\u00f5es, \u00e9 importante que elas n\u00e3o interfiram uma na outra. Essa \u00e9 a propriedade de isolamento.<\/p>\n<p>O SQL define 4 n\u00edveis de isolamento:<\/p>\n<ul>\n<li>LEITURA N\u00c3O CONFIRMADA<\/li>\n<li>LEITURA CONFIRMADA<\/li>\n<li>LEITURA REPET\u00cdVEL<\/li>\n<li>SERIALIZ\u00c1VEL<\/li>\n<\/ul>\n<p>\nVamos considerar cada n\u00edvel separadamente. Os custos de implementa\u00e7\u00e3o de cada n\u00edvel aumentam quase exponencialmente.<\/p>\n<p><b>LEITURA N\u00c3O CONFIRMADA<\/b> \u2014 este \u00e9 o n\u00edvel mais baixo de isolamento, mas o mais r\u00e1pido. As transa\u00e7\u00f5es podem ler as mudan\u00e7as feitas umas pelas outras.<\/p>\n<p><b>LEITURA CONFIRMADA<\/b> \u2014 este \u00e9 o pr\u00f3ximo n\u00edvel de isolamento que \u00e9 um compromisso. As transa\u00e7\u00f5es n\u00e3o podem ler as mudan\u00e7as feitas umas pelas outras at\u00e9 o commit, mas podem ler quaisquer altera\u00e7\u00f5es feitas ap\u00f3s o commit.<\/p>\n<p>Se tivermos uma longa transa\u00e7\u00e3o T1, durante a qual ocorreram commits nas transa\u00e7\u00f5es T2, T3 ... Tn, que trabalharam com os mesmos dados que T1, ao solicitar dados em T1, sempre receberemos resultados diferentes. Esse fen\u00f4meno \u00e9 chamado de leitura n\u00e3o repet\u00edvel.<\/p>\n<p><b>LEITURA REPET\u00cdVEL<\/b> \u2014 neste n\u00edvel de isolamento n\u00e3o temos o fen\u00f4meno de leitura n\u00e3o repet\u00edvel, pois para cada solicita\u00e7\u00e3o de leitura de dados \u00e9 criado um snapshot dos dados resultantes e, ao reutiliz\u00e1-los nesta mesma transa\u00e7\u00e3o, s\u00e3o utilizados os dados do snapshot. No entanto, neste n\u00edvel de isolamento \u00e9 poss\u00edvel a leitura de dados fantasmas. Refere-se \u00e0 leitura de novas linhas que foram adicionadas por transa\u00e7\u00f5es paralelas confirmadas.<\/p>\n<p><b>SERIALIZ\u00c1VEL<\/b> \u2014 o mais alto n\u00edvel de isolamento. Ele \u00e9 caracterizado pelo fato de que os dados de alguma forma utilizados na transa\u00e7\u00e3o (leitura ou altera\u00e7\u00e3o) tornam-se acess\u00edveis a outras transa\u00e7\u00f5es apenas ap\u00f3s a conclus\u00e3o da primeira transa\u00e7\u00e3o.<\/p>\n<p>Para come\u00e7ar, vamos verificar se h\u00e1 isolamento das opera\u00e7\u00f5es na transa\u00e7\u00e3o em rela\u00e7\u00e3o ao fluxo principal. Vamos abrir 2 janelas 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>\nN\u00e3o h\u00e1 isolamento. Um fluxo v\u00ea o que o segundo, que abriu a transa\u00e7\u00e3o, est\u00e1 fazendo.<\/p>\n<p>Vamos ver se as transa\u00e7\u00f5es em diferentes fluxos veem o que acontece dentro delas. <\/p>\n<p>Vamos abrir 2 janelas de terminal e abrir 2 transa\u00e7\u00f5es em paralelo.<\/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>\nTransa\u00e7\u00f5es paralelas veem os dados umas das outras. Assim, temos o n\u00edvel mais simples, mas tamb\u00e9m o mais r\u00e1pido de isolamento: READ UNCOMMITTED.<\/p>\n<p>Isso era de se esperar para globais, para os quais a performance sempre foi uma prioridade. <\/p>\n<p>O que fazer, se precisarmos de um n\u00edvel de isolamento mais alto em opera\u00e7\u00f5es sobre globais?<\/p>\n<p>Aqui, \u00e9 preciso pensar sobre por que os n\u00edveis de isolamento s\u00e3o necess\u00e1rios e como eles funcionam.<\/p>\n<p>O n\u00edvel mais alto de isolamento, SERIALIZE, significa que o resultado de transa\u00e7\u00f5es executadas em paralelo \u00e9 equivalente \u00e0 sua execu\u00e7\u00e3o sequencial, garantindo a aus\u00eancia de colis\u00f5es.<\/p>\n<p>Isso podemos fazer com bloqueios adequados em ObjectScript, que t\u00eam uma variedade de formas de aplica\u00e7\u00e3o: podemos fazer bloqueios normais, incrementais, m\u00faltiplos com o comando <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>N\u00edveis mais baixos de isolamento s\u00e3o compromissos destinados a aumentar a velocidade de opera\u00e7\u00e3o do banco de dados.<\/p>\n<p>Vamos ver como podemos alcan\u00e7ar diferentes n\u00edveis de isolamento com bloqueios.<\/p>\n<p>Este operador permite obter n\u00e3o apenas bloqueios exclusivos, necess\u00e1rios para modificar dados, mas tamb\u00e9m bloqueios compartilhados, que podem ser obtidos por v\u00e1rios fluxos simultaneamente, quando precisam ler dados que n\u00e3o devem ser alterados por outros processos durante a leitura.<\/p>\n<p>Mais detalhes sobre o m\u00e9todo de bloqueio de duas fases em russo e ingl\u00eas:<\/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\">Bloqueio de duas fases<\/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>A complexidade reside no fato de que durante a transa\u00e7\u00e3o, o estado do banco pode estar inconsistente, no entanto, esses dados inconsistentes s\u00e3o vis\u00edveis para outros processos. Como evitar isso?<\/p>\n<p>Faremos isso com bloqueios, criando janelas de visibilidade onde o estado do banco estar\u00e1 consistente. E todas as chamadas a essas janelas de visibilidade de estado consistente ser\u00e3o controladas por bloqueios.<\/p>\n<p>As bloqueios compartilhados de dados duplicados podem ser adquiridos por v\u00e1rios processos. Esses bloqueios impedem que outros processos alterem os dados, ou seja, s\u00e3o usados para formar janelas de estado consistente do banco de dados.<\/p>\n<p>Os bloqueios exclusivos s\u00e3o utilizados para altera\u00e7\u00f5es de dados - esse tipo de bloqueio pode ser adquirido apenas por um \u00fanico processo. Um bloqueio exclusivo pode ser adquirido por:<\/p>\n<ol>\n<li>Qualquer processo, se os dados estiverem livres.<\/li>\n<li>Somente o processo que possui um bloqueio compartilhado sobre esses dados e solicitou primeiro o bloqueio exclusivo.<\/li>\n<\/ol>\n<p>\n<img decoding=\"async\" alt=\"Transa\u00e7\u00f5es em globais InterSystems IRIS\" src=\"\/wp-content\/uploads\/2019\/07\/bb91ed1268925bc1b9266763ab82646a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nQuanto mais estreita for a janela de visibilidade, mais tempo outros processos ter\u00e3o que esperar, mas mais consistente pode ser o estado do banco de dados nela.<\/p>\n<p><b>READ_COMMITED<\/b> \u2014 a ess\u00eancia deste n\u00edvel \u00e9 que vemos apenas os dados confirmados de outras transa\u00e7\u00f5es. Se os dados em outra transa\u00e7\u00e3o ainda n\u00e3o foram confirmados, vemos sua vers\u00e3o antiga.<\/p>\n<p>Isso nos permite paralelizar o trabalho em vez de esperar pela libera\u00e7\u00e3o do bloqueio.<\/p>\n<p>Sem artif\u00edcios especiais, n\u00e3o conseguiremos ver a vers\u00e3o antiga dos dados no IRIS, ent\u00e3o teremos que nos basear em bloqueios.<\/p>\n<p>Consequentemente, teremos que permitir a leitura de dados s\u00f3 em momentos de consist\u00eancia, usando bloqueios compartilhados.<\/p>\n<p>Suponha que temos um banco de usu\u00e1rios ^person, que transferem dinheiro entre si.<\/p>\n<p>O momento da transfer\u00eancia da pessoa 123 para a pessoa 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>\nO momento em que se solicita a quantidade de dinheiro da pessoa 123 antes da dedu\u00e7\u00e3o deve ser acompanhado de um bloqueio exclusivo (por padr\u00e3o):<\/p>\n<pre><code class=\"bash\">LOCK +^person(123)\nWrite ^person(123)<\/code><\/pre>\n<p>\nE se precisar mostrar o estado da conta no painel, pode-se usar um bloqueio compartilhado ou n\u00e3o usar bloqueio algum:<\/p>\n<pre><code class=\"bash\">LOCK +^person(123)#\u201dS\u201d\nWrite ^person(123)<\/code><\/pre>\n<p>\nNo entanto, se admitirmos que as opera\u00e7\u00f5es com o banco de dados s\u00e3o realizadas praticamente instantaneamente (lembro que os globais s\u00e3o uma estrutura muito mais de baixo n\u00edvel do que uma tabela relacional), a necessidade desse n\u00edvel diminui.<\/p>\n<p><b>LEITURA REPET\u00cdVEL<\/b> \u2014 neste n\u00edvel de isolamento, \u00e9 permitido que haja v\u00e1rias leituras de dados que podem ser alteradas por transa\u00e7\u00f5es paralelas. <\/p>\n<p>Consequentemente, teremos que colocar bloqueios compartilhados para a leitura de dados que alteramos e bloqueios exclusivos para os dados que modificamos.<\/p>\n<p>O operador LOCK permite detalhar bloqueios necess\u00e1rios em um \u00fanico operador, que podem ser muitos.<\/p>\n<pre><code class=\"bash\">LOCK +^person(123, amount)#\u201dS\u201d\nleitura ^person(123, amount)<\/code><\/pre>\n<p>\noutras opera\u00e7\u00f5es (durante esse tempo, fluxos paralelos tentam alterar ^person(123, amount), mas n\u00e3o conseguem)<\/p>\n<pre><code class=\"bash\">LOCK +^person(123, amount)\nmodifica\u00e7\u00e3o ^person(123, amount)\nLOCK -^person(123, amount)\n\nleitura ^person(123, amount)\nLOCK -^person(123, amount)#\u201dS\u201d<\/code><\/pre>\n<p>\nAo listar bloqueios separados por v\u00edrgula, eles s\u00e3o tratados sequencialmente, mas se fizer assim:<\/p>\n<pre><code class=\"bash\">LOCK +(^person(123),^person(242))<\/code><\/pre>\n<p>\neles ser\u00e3o tratados atomicamente todos de uma s\u00f3 vez.<\/p>\n<p><b>SERIALIZE<\/b> \u2014 teremos que aplicar bloqueios de forma que, no final, todas as transa\u00e7\u00f5es que compartilham dados sejam executadas sequencialmente. Para essa abordagem, a maioria dos bloqueios deve ser exclusiva e abranger as menores \u00e1reas globais para maior desempenho.<\/p>\n<p>No que diz respeito a retiradas de fundos da global ^person, apenas o n\u00edvel de isolamento SERIALIZE \u00e9 aceit\u00e1vel, j\u00e1 que o dinheiro deve ser gasto estritamente de forma sequencial, caso contr\u00e1rio, \u00e9 poss\u00edvel gastar a mesma quantia v\u00e1rias vezes.<\/p>\n<h2>4. Perman\u00eancia<\/h2>\n<p>\nRealizei testes com a interrup\u00e7\u00e3o abrupta do cont\u00eainer atrav\u00e9s de<\/p>\n<pre><code class=\"bash\">docker kill my-iris<\/code><\/pre>\n<p>\nO banco se adaptou bem. Nenhum problema foi identificado.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>\nPara globais no InterSystems IRIS, h\u00e1 suporte a transa\u00e7\u00f5es. Elas s\u00e3o realmente at\u00f4micas e confi\u00e1veis. No entanto, para garantir a consist\u00eancia do banco de dados nas globais, \u00e9 necess\u00e1rio o esfor\u00e7o do programador e o uso de transa\u00e7\u00f5es, pois n\u00e3o h\u00e1 complexas constru\u00e7\u00f5es embutidas, como chaves estrangeiras.<\/p>\n<p>O n\u00edvel de isolamento nas globais sem o uso de bloqueios \u00e9 READ UNCOMMITED, e com o uso de bloqueios, pode-se garantir at\u00e9 o n\u00edvel SERIALIZE.<\/p>\n<p>A corre\u00e7\u00e3o e a velocidade das transa\u00e7\u00f5es nas globais dependem muito da habilidade do programador: quanto mais amplamente s\u00e3o usadas bloqueios compartilhados durante a leitura, maior \u00e9 o n\u00edvel de isolamento, e quanto mais restritivamente s\u00e3o usadas bloqueios exclusivos, maior \u00e9 a velocidade.<br \/>\n<br \/>Fonte: <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.3 - 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\/pt\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\/pt\/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\udd47Transa\u00e7\u00f5es em globais InterSystems IRIS | ProHoster","description":"O SGBD InterSystems IRIS suporta estruturas interessantes.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/tranzaktsii-v-globalah-intersystems-iris","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/36650","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=36650"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/36650\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/27448"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=36650"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=36650"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=36650"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}