<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog da Especializa</title>
	<atom:link href="http://especializa.com.br/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://especializa.com.br/blog</link>
	<description>Novidades, curiosidades e nosso ponto-de-vista sobre o mercado de TI</description>
	<lastBuildDate>Tue, 15 May 2012 14:33:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>HTML5 nao e apenas HTML5</title>
		<link>http://especializa.com.br/blog/2012/05/15/html5-nao-e-apenas-html5/</link>
		<comments>http://especializa.com.br/blog/2012/05/15/html5-nao-e-apenas-html5/#comments</comments>
		<pubDate>Tue, 15 May 2012 07:47:39 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=233</guid>
		<description><![CDATA[Vamos resolver algumas confusões criadas na evolução dos browsers, em foco o que é exatamente o HTML em sua versão 5 (que não é a quinta).]]></description>
			<content:encoded><![CDATA[<p>Recentemente, um aluno me procurou querendo explicações sobre o que exatamente era o HTML5. Parece uma pergunta relativamente simples, mas o cão mora nos detalhes. Lembro que umas semanas antes indiquei um bom livro sobre HTML5 para outro aluno e caí na besteira de indicar um livro sobre o HTML5 que tá na moda, mas ele precisava mesmo era de um livro de HTML, em sua versão mais atualizada.</p>
<p>Este post é direcionado aos puros de coração que jamais (ou quase nunca) viram HTML e vejamos então porque considero que HTML5 não é apenas HTML5.<span id="more-233"></span></p>
<p>Esta linguagem é um conjunto de marcações criado a partir da antiga SGML (Standard Generalized Markup Language), uma distinta senhora que deu à luz nossa conhecida XML. Ou seja, a SGML (que Deus a tenha em um bom lugar) e sua cria XML (eXtensible Markup Language) foram concebidas na intenção de se estruturar textos de modo que uma máquina conseguisse conversar com a outra apenas entendendo o formato.</p>
<p>Isso sempre existiu, mas o interessante foi utilizar um formato humanamente legível.  Hein? É o seguinte, eu escrevo um texto e salvo em um arquivo com algumas marcações de início e fim do conteúdo:</p>
<p>&lt;dados&gt;<br />
&lt;noticia id=&#8221;1&#8243;&gt;<br />
&lt;titulo&gt;HTML5 não é apenas HTML5&lt;titulo&gt;<br />
&lt;data&gt;2012-05-14 17:40:10&lt;/data&gt;<br />
&lt;chamada&gt;Ei, tu, vem ler esse post &#8220;massa&#8221; aqui&lt;/chamada&gt;<br />
&lt;/noticia&gt;<br />
&lt;/dados&gt;</p>
<p>Embora eu tenha usado um formato (vou chamar de sintaxe a partir de agora) estranho para um veterinário ornitólogo, certamente ele é capaz de entender (talvez até seus pacientes sejam capazes de entender).</p>
<p>É essa tal de sintaxe que padroniza as coisas. Assim, um documento XML válido é um mero arquivo de texto que segue as regras dessa sintaxe para expor qualquer conteúdo, em qualquer dialeto. Basta que sigamos seus mandamentos:</p>
<p>- O conteúdo é demarcado por tags, também chamadas nós, que são esses nomezinhos cercados por sinais de menor e maior que.</p>
<p>- Toda marcação é encerrada com o  mesmo nome da tag precedido por uma barra. &lt;tag&gt;Conteudo. Também chamado de corpo&lt;/tag&gt;</p>
<p>- As tags são fechadas na ordem inversa de abertura. Não deve haver tag interna fechando depois da externa.</p>
<p>- Tudo deve vir contido em uma tag (nó) raiz, conhecida por document element.</p>
<p>- Tags não precisam ter corpo. Quando não têm, usamos uma barra no fim para indicar isso: &lt;tagsemcorpo /&gt;</p>
<p>Existem ainda algumas regrinhas 10 centavos menos simples que eu não tô a fim de citar agora.</p>
<p>Pois bem, o HTML é um dialeto oriundo desse conjunto de regras. Quem escreve um documento HTML escreve (ou deveria escrever), em uma sintaxe válida (documento XML bem formado), um conteúdo dentro de tags que os browsers entendem (ou deveriam entender).</p>
<p>O W3C é o consórcio que nasceu no intuito de por ordem na já existente guerra de navegadores na época de Cabral, Colombo, Netscape e Internet Explorer. #FAIL. O W3C nunca conseguiu a utopia de criar um padrão totalmente aceito e devidamente implementado, e por muito tempo, sequer inovou algo neste padrão.  Eu gosto de dividir essa história em 4 etapas:</p>
<h2>1. Web Conteudeozóica</h2>
<p>Nessa era, os browsers eram meros visualizadores de arquivos HTML sem muita preocupação estética. Eu nasci há 10 mil anos atrás e pude presenciar que nesse tempo cunhou-se o termo página, uma vez que o protocolo HTTP havia sido criado para servir uma &#8220;folha&#8221; de documento por vez.  Naquele tempo, a tag &lt;p&gt; significava parágrafo. Simples assim. &lt;p&gt; não siginificava necessariamente que  haveria uma separação de X pixels do parágrafo atual para o próximo conteúdo da página, apenas que era um parágrafo. O uso de tags sem sentido semântico era muito baixo.</p>
<h2>2. Parnasianismo Webial</h2>
<p>Nessa era, surgiram os ditos &#8220;profissionais&#8221; de Web. Eram seres bizarros só preocupados em como o tal conteúdo seria exibido no browser (quem disser que eu era um deles está enganado, eu nego tudo com veemência Malufiana).</p>
<p>O formato valia mais do que o conteúdo. Quem se importava com os cegos? Todo mundo enchia as páginas de imagens (como o famigerado spacer.gif) e outros elementos inacessíveis a buscadores.</p>
<p>Esses alquimistas faziam páginas lindas. A partir do mais tosco e grotesco código-fonte saiam as mais finas flores do campo. Reza a lenda que as páginas eram até cheirosas, embora paradas, estáticas &#8230; <a title="Mais sobre esse belo gênero HTML" href="http://pt.wikipedia.org/wiki/Natureza-morta" target="_blank">natureza morta</a>.</p>
<p>A fim de tornar as coisas mais vivas, foram adotados novos (nem tanto) artifícios denominados CSS (cascade stylesheet) e Javascript (aluno meu que chamar de Java leva um potó no olho esquerdo). O primeiro com o intuito de aplicar a estética e o segundo para responder a estímulos do usuário e programar algumas pirotecnias e validações de campos de formulários.</p>
<p>Quando o trio foi devidamente apresentado às sociedades da época, o HTML passou a ser chamado de DHTML (Dynamic HTML) e foi aí que começou todo o problema que quero relatar aqui. O HTML sem Javascript ou CSS não tinha cheiro nem sabor, mas juntando tudo, a trinca passou a se chamar DHTML. Estudar DHTML significava estudar as três irmãs metralha.</p>
<h3>2.1 Dinastia Explórica</h3>
<p>Após o ataque do Alaska a Vladvostok, os exércitos Azuis da Microsoft deram início ao maior império Web de todos os tempos. O Netscape, então absoluto nos tempos românticos da Web conteudozoicamente acadêmica, aqui definhava até o couro e o osso.</p>
<p>Nessa era parnasianamente esteticóidica, o Rei William (Tio Biu para os chegados) ditava as regras e nós, meros trabalhadores havíamos virado escravos de ferramentas esquisitas como o Macromedia Dreamweaver (brincadeirinha&#8230; toda brincadeira tem um fundo de verdade, já dizia minha avó) ou o monstro MS Front-Page, este último é melhor falar baixo pra não invocá-lo das trevas.</p>
<p>Cheguei a usar também Adobe Image Ready e até hoje sofro de problemas psicológicos e alucinações com slices.</p>
<p>Era rowspan=25 (isso, sem aspas mesmo) pra lá, bgcolor pra cá e &lt;font&gt; pra todo lado. Tag &lt;b&gt; (&#8221;bold&#8221;, negrito em aramaico) que abria em uma célula de uma tabela e nem precisava fechar, bastava fechar a célula da tabela que o IE pegava. O Netscape antigo sequer era capaz de renderizar a tabela se esta não estivesse bem montada.</p>
<h3>2.2 O fim de uma era sinistra</h3>
<p>Todo montador (nós éramos chamados assim pela sociedade da época &#8230; puro bulling) usava tag &lt;td&gt; (&#8221;t&#8221; de table, &#8220;d&#8221; de célula &#8230; isso mesmo, deve ser por causa do aramaico) pra tudo. Layouts eram sempre feitos com tabelas.</p>
<p>Nessa época, a fundação Mozilla trouxe do jogo do Sonic uma raposa que comeu logo 10% do market-share do IE. O Firefox veio para ser um browser rápido (um dia ele foi o mais rápido sim, pode acreditar), com idéias novas (algumas dizem que foram copiadas do Opera, mas tudo bem, foi por uma nobre causa) e capaz de entender algumas das bizarrices explóricas.  Paralelo a isso, os montadores ao redor do mundo se organizavam em guetos e planejavam passeatas em defesa do triunvirato: HTML para conteúdo, CSS para estética e Javascript para programação das funcionalidades. Juntos eles formavam o Capitão Planeta.</p>
<h2>3. Modernismo HTEmiélico</h2>
<p>Finalmente o conteúdo passou a ser mais importante do que a forma. Os cegos começaram timidamente a enxergar a Web e o Google capitaneou uma revolução silenciosa em busca do melhor uso das tags semânticas como &lt;h1&gt;, &lt;h2&gt;, &lt;p&gt;, &lt;th&gt;, &lt;ul&gt;, &lt;ol&gt;, etc.</p>
<h3>3.1 A promiscuidade dos browsers</h3>
<p>A guerra desenfreada de browsers já havia os transformado em máquinas trituradoras de arquivos bem ou até mal formados.</p>
<p>Chrome e Safari foram dois bólidos montados a partir do mesmo layout engine, o WebKit. Layout Engines, ou simplesmente engenhos são o coração do interpretador HTML do browser. Por exemplo, IE-Trident, Firefox-Gecko, Opera-Presto são como RedBull-Renault ou McLaren-Mercedes da Fórmula 1. O Chrome e o Safari são fabricados até hoje com o mesmo motor WebKit embora com pequenos ajustes pra cada lado.</p>
<p>Diga-se de passagem, a história dos layout engines merecia um capítulo à parte. A assinatura de um Chrome hoje é praticamente o nome de D. Pedro I.</p>
<p><span style="font-family: monospace; line-height: normal; font-size: medium;"><strong>Mozilla</strong>/5.0 (Macintosh; Intel Mac OS X 10_7_3) <strong>AppleWebKit</strong>/535.19 (<strong>KHTML</strong>, like <strong>Gecko</strong>)<strong>Chrome</strong>/18.0.1025.168 <strong>Safari</strong>/535.19 </span>é o nome do Chrome 18 no Mac. Veja nas palavras em negrito a quantidade de menções aos concorrentes.</p>
<h3>3.2 A ditadura do W3C</h3>
<p>O W3C, tão ovacionado por todos nós até então, resolveu pôr as manguinhas de fora e mostrar que nem era assim tão santo. Acabou com a HTML e seu pseudônimo DHTML e decretou que os browsers a partir dali deviam suportar a XHTML (XML + HTML). O que é isso companheiro? A HTML já não era um dialeto escrito em XML? Todo documento HTML já não seria um documento XML bem formado?  A resposta é quase.</p>
<p>O W3C lançou um pacote de austeridade econômica denominado Web Standards. Nele, toda tag de cunho estético foi banida da HTML. O mesmo para certos atributos das tags preexistentes como os cellpadding e cellspacing das tabelas. Aliás, muita gente indevidamente achou que deveria matar as tabelas também, o termo tableless virou cool e muito conteúdo tabular por aí passou a ser montado sobre dezenas de divs. Pura arte cubista que fez os sites precisarem ser testados exaustivamente nos 5 browsers mais populares.</p>
<p>O plano do W3C foi perverso. Todas as furiosas regras XML recaíram sobre incautos documentos HTML. Tags que não possuíam corpo precisavam da barra final. Ex.: &lt;br&gt; deveria ser &lt;br /&gt;. Todo atributo deveria ser escrito como nome=&#8221;valor entre aspas&#8221;, etc. Todo XHTML precisava definir uma marcação inicial denominada DOCTYPE. No XML, DOCTYPEs servem documento validadores do dialeto usado no seu documento XML.</p>
<p>Como diria Virgulino: &#8220;Se eu entendi, eu cegue!&#8221;</p>
<p>Ora, XMLs são documentos com quaisquer tags, basta que o escritor e o leitor conheçam o dialeto (quais tags podem vir onde e quando) para se dar a comunicação. DOCTYPEs são declarações que apontam para documentos de definição (DTDs). Estes por sua vez dizem: &#8220;&#8230;essa tag vem aqui, dentro dela só pode ter essa ou essa, primeiro vem aquela, etc e tal&#8230;&#8221;.</p>
<p>Leitores XML sempre se valeram dos DTDs (mais modernosamente dos XML Schemas) para validar o documento antes de tentar ler. Eles servem de garantia de grafia do documento. Acontece que os escritores dos HTMLs sempre fomos nós e os leitores HTML sempre foram os browsers. As tags sempre foram praticamente as mesmas. Nenhum browser seria maluco de executar uma rotina de validação antes de começar a interpretar nossos documentos para não perder tempo.</p>
<p>No entanto, por um lado, o plano W3Cêico deu certo. O Google agradeceu a melhor organização média das páginas Web que seguiram os Web Standards e os browsers começaram a ser mais rígidos e padronizados. Eles utilizaram os DOCTYPEs não para validar mas para definir seu nível de comportamento. Ou seja, &#8220;se um documento vier sem DOCTYPE eu vou ler como eu sempre o li, se ele vier com o DOCTYPE XHTML Transitional eu vou passar a exigir algumas regras de boa formatação, se for XHTML Strict eu vou ligar minha rigorosidade no talo&#8221;.</p>
<h3>3.3 RIA W3C RIA</h3>
<p>Apesar da melhora desta fase da Web, todo mundo estava incomodado com a pobreza dos Web Standards. A DHTML havia trazido mais riqueza em sua época, mas a XHTML focou apenas em rigidez sintática e melhor aplicação semântica das marcações existentes.</p>
<p>Enquanto o W3C dormia em berço esplêndido, o mundo já discutia as novas mágicas Javascrípticas como a AJAX, requisições que os browsers faziam aos servidores Web se atualizar a página. Aliás, o próprio termo página ficou defasado. Os projetos Web agora são programas. O mundo viu emergir os softwares como serviço e a HTML naturalmente deveria ser a linguagem padrão dessa evolução.</p>
<p>O termo RIA (Rich Internet Application) foi exaltado pela Adobe para aplicativos Web que usavam Flash, mas passou também a abranger a trinca XHTML+CSS+Javascript.</p>
<p>Bibliotecas como a jQuery, YUI e ExtJS surgiram e se fortaleceram para simplificar o trabalho muitas vezes tedioso de se constuir RIA usando Javascript. O CSS até que evoluiu e muita coisa melhorou em sua versão 3.</p>
<p>Mesmo assim, dois gigantes ainda hibernavam, o próprio W3C que não inovou praticamente nada e a Microsoft.</p>
<p>Isso mesmo, a Microsoft. Há duas teorias para fato do Internet Explorer ter se tornado o ser mais odiado do planeta. A primeira mais realista é de pura falta de feeling da empresa líder do mercado que achou que nada abalaria seu belo produto. A segunda mais fantasiosa fala até que a Microsoft não queria a evolução da RIA e do software como serviço, pois pense bem, se todo programa rodasse na Web, ela seria a plataforma necessária e não mais o Windows.</p>
<h2>4. Semântica pós-moderna</h2>
<p>Conspirações à parte, a Mozilla (Gepeto do Firefox), a Opera, a Apple e a Google se cansaram do W3C e fundaram uma sociedade maçônica denominada WhatWG para dominar o mundo. Eles queriam obviamente aumentar seu market-share, fatiando o mercado do IE, mas principalmente, queriam que a Web evoluísse.</p>
<p>As marcações deveriam ser mais semânticas. Ou seja, queremos saber se no meio do conteúdo tem um telefone, um endereço de uma empresa e não apenas que ali é um parágrafo. Isso é muito genérico. Movimentos como os do RDFa e Microformats foram absorvidos no novo Microdata e diversas novas tags surgiram.</p>
<h3>4.1 HTML em sua versão 5 e a HTML5</h3>
<p>A XHTML não trouxe a semântica almejada, mas sim uma carga de rigidez que tornou os projetos Web mais enfadonhos. Seria interessante diminuir esse rigor. A WhatWG propôs então a ressurreição da HTML. Esta havia morrido na versão 4 para dar lugar à XHTML, então naturalmente sua versão foi chamada de 5.</p>
<p>Ela trouxe novas tags estruturais como &lt;header&gt;, &lt;section&gt;, &lt;article&gt;, &lt;footer&gt;, novas marcações semânticas como &lt;progress&gt;, &lt;meter&gt; e &lt;figure&gt;, suporte sem plugins a áudio e vídeo, suporte a imagens inline vetorias (&lt;svg&gt;) e bitmaps (&lt;canvas&gt;), novos atributos para simplificar tarefas corriqueiras como o placeholder.</p>
<p>Enfim, a HTML em sua versão 5 foi uma revolução HTEmiélica de conteúdo Web.</p>
<p>No entanto, é necessário contextualizar que há muitas gerações que ninguém trabalha apenas com HTML, mas com a tríplice coroa HTML+CSS+Javascript. Como as novidades não vieram apenas na HTML, a CSS já estava em fase avançada de adoção de sua versão 3 pelos browsers e a Javascript há muito que ninguém sabia mais qual a versão exata dela, todo o conjunto de novidades ficou sob o guarda-chuva HTML5.</p>
<p>Em outras palavras, tanto a CSS3 quanto gigantesca melhoria no Javascript (Web Workers, Websockets, geolocation, Session storage, manipulações do canvas, do audio e do vídeo, etc, etc, etc, etc e bote etc nisso) ficaram dentro do assunto HTML5.</p>
<p>Toda essa história foi para dizer que a HTML5 virou padrão W3C, um padrão que deverá ser oficializado em 2014 mas que já é amplamente suportado pelos browsers (até pelo IE, embora ainda estejamos ansiosos para ver o IE 10, uma vez que o 9 deixou muito a desejar).</p>
<p>A nomenclatura HTML5 é hoje dada ao trio e não apenas ao conteúdo HTML.</p>
<p>O aluno que me fez escrever esse texto até as 4:27 da manhã havia me falado sobre um comentário reverberado no encontro Pernambuco.js que ocorreu no mês passado (que infelizmente não pude prestigiar): &#8220;Ninguém pode dizer que sabe HTML5 sem saber Javascript&#8221;.</p>
<p>Dependendo do ponto de vista, concordo plenamente com a frase, mas isso até atrapalhou esse que então ainda não era meu aluno e o fez pensar em estudar Javascript antes de estudar HTML.</p>
<p>Portanto lembre-se HTML5 não é apenas HTML em sua versão 5.</p>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2012/05/15/html5-nao-e-apenas-html5/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>FaceBook e a prova que um sistema em PHP e escalonavel e leve</title>
		<link>http://especializa.com.br/blog/2010/12/22/facebook-e-a-prova-que-um-sistema-em-php-e-escalonavel-e-leve/</link>
		<comments>http://especializa.com.br/blog/2010/12/22/facebook-e-a-prova-que-um-sistema-em-php-e-escalonavel-e-leve/#comments</comments>
		<pubDate>Wed, 22 Dec 2010 17:12:01 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[especializa]]></category>
		<category><![CDATA[jennifer]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=230</guid>
		<description><![CDATA[Por Jennifer Payne,
Ao atingir 500 milhões de usuários o FaceBook prova que o PHP é um  sistema sólido, leve e seguro. Afinal, como disse a equipe do FaceBook  ao Alemão Sebastian Bergmann, que faz parte da equipe do PHPUnit, um bug  que atinja 1% dos usuários do FB (FaceBook), atinge na verdade [...]]]></description>
			<content:encoded><![CDATA[<p><em>Por Jennifer Payne,</em></p>
<p>Ao atingir 500 milhões de usuários o FaceBook prova que o PHP é um  sistema sólido, leve e seguro. Afinal, como disse a equipe do FaceBook  ao Alemão Sebastian Bergmann, que faz parte da equipe do PHPUnit, um bug  que atinja 1% dos usuários do FB (FaceBook), atinge na verdade 5  milhões de pessoas. Então o FB é a prova viva de que podemos sim, ter um  sistema seguro, robusto, leve e acessível em PHP.</p>
<div>Este post é mais para parabenizar toda a comunidade, os  amigos e professores da Especializa e também para ajudar vocês a  apresentar um forte argumento de venda, quando algum cliente  questionar: - Essa tecnologia é segura mesmo?</div>
<div></div>
<div><em>Quer prova maior?</em></div>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/12/22/facebook-e-a-prova-que-um-sistema-em-php-e-escalonavel-e-leve/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pensou PHP, pensou Especializa!</title>
		<link>http://especializa.com.br/blog/2010/08/13/pensou-php-pensou-especializa/</link>
		<comments>http://especializa.com.br/blog/2010/08/13/pensou-php-pensou-especializa/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 06:32:26 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[especializa]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=222</guid>
		<description><![CDATA[Este slogan já tem 5 anos e se depender da gente vai durar mais 50.
Fomos a primeira empresa no Brasil a preparar para a certificação oficial Zend, na época para o PHP 4. Nossos módulos anteriores certamente somam um dos melhores e mais completos cursos de  PHP do nosso país. Em Recife simplesmente não há [...]]]></description>
			<content:encoded><![CDATA[<p>Este slogan já tem 5 anos e se depender da gente vai durar mais 50.</p>
<p>Fomos a primeira empresa no Brasil a preparar para a certificação oficial Zend, na época para o PHP 4. Nossos módulos anteriores certamente somam um dos melhores e mais completos cursos de  PHP do nosso país. Em Recife simplesmente não há comparação.</p>
<p>Mas o que era bom não poderia ficar obsoleto. Após esses 5 anos de sucesso absoluto, tivemos a ousadia de atualizar seu formato para atender às necessidades atuais e contemplar melhor os novos recursos da linguagem.</p>
<p>Clique abaixo e confira todas as novidades.</p>
<p><span id="more-222"></span></p>
<p>Iniciamos nossos treinamentos em meados de 2005, exatamente com uma turma do então curso PHP Avançado. Logo criamos a suíte de cursos que contava com os módulos PHP Programmer (básico), PHP Developer (avançado) e PHP Certified Engineer (preparatório para a Zend Certified Engineer &#8211; PHP 4 Certification). Após a atualização da prova para contemplar a versão 5, ajustamos nosso módulo preparatório e pouco depois percebemos que seria interessante criar o módulo PHP Expert antes dele.</p>
<p>Seguimos uma filosofia que vem dando muito certo e podemos dizer que o PHP foi o laboratório deste formato também adotado em outros cursos preparatórios como Java e LPI. Primeiro ensinamos em módulos práticos, voltados ao dia-a-dia do profissional. Neles, todo o assunto da prova é abordado, além de assuntos que são importantes mas não são requisitados por ela. Só então o aluno ingressa no preparatório para certificação, com certamente muito mais confiança em seus conhecimentos.</p>
<p>Hoje, contamos com um <a title="Grupo Especializa PHP" href="http://groups.google.com/group/especializa-php" target="_blank">Grupo de Estudos</a> de altíssimo nível com alunos, ex-alunos, professores e demais interessados na linguagem.</p>
<p>Confira abaixo o que mudou em cada módulo:</p>
<h2>PHP Programmer</h2>
<p>Sem dúvida é difícil mexer em um dos cursos mais importantes que temos. Aqui, não tratávamos de orientação a objetos, mas percebemos que ela já se faz presente em praticamente todas as empresas que desenvolvem softwares em PHP. Além disso, desde o PHP 5.0, toda e qualquer nova API é escrita orientada a objetos.</p>
<p>Resolvemos aumentar a carga-horária para antecipar conceitos como o que são objetos, classes, atributos, métodos e como é interessante usufruir de recursos OO como o PHPMailer para envio de emails, PDO para abstração de SGBDs.</p>
<p>Duração: 45 horas.</p>
<h2>PHP Developer</h2>
<p>Neste módulo, ensinamos como modelar um sistema orientado a objetos e trouxemos muita coisa do Expert. Chegamos a desenvolver um framework MVC simples montado sobre funcionalidades como reescritas de URLs via .htaccess com ModRewrite, expressões regulares, internacionalização, reflection e muito mais.</p>
<p>Abordamos o Doctrine 2.0, um fantástico sistema de mapeamento objeto relacional. Discutimos padrões de projeto e arquitetura.</p>
<p>No final, o clássico projeto da nossa Loja Virtual ganhou um roupagem nova e resolvemos abordar geração de boletos bancários.</p>
<p>Duração: 48 horas</p>
<h2>PHP Expert</h2>
<p>Esse é o nosso laboratório de novas funcionalidades. Foi aqui que primeiramente citamos novas funcionalidades do PHP 5.3 como namespaces e closures (hoje assuntos de módulos anteriores). Focamos no estudo de Web Services, apresentando primeiro como funcionam os Sockets TCP e como trabalhar com documentos XML. Utilizamos Web Services para buscar serviços conhecidos de redes sociais como o Twitter e o Facebook.</p>
<p>Introduzimos e discutimos como o PHP se integra com interfaces ricas <a href="http://www.especializa.com.br/flex" target="_blank">Flex</a> e <a href="http://www.especializa.com.br/ajax" target="_blank">Ajax</a>. Tudo bem, deixamos o gostinho para que quem quiser se aprofundar em nossos cursos específicos. Vemos ainda a geração de binários como imagens, documentos PDF e a alimentação de documentos XML utilizados pela biblioteca de relatório gráfico em flash Fusion Charts.</p>
<p>Duração: 48 horas</p>
<h2>PHP Certified Engineer</h2>
<p>Para este módulo, elaboramos questões no nível da prova e realizamos simulados do decorrer das aulas. Também foi ampliado para melhor atender.</p>
<p>Duração: 40 horas</p>
<p>Fizemos tudo isso, pensando em lhe oferecer o que há de melhor em cursos de PHP. Mas, se você tem alguma critica ou sugestão de formato, pode descer a lenha nos comentários abaixo.</p>
<p><a href="http://www.especializa.com.br/php" target="_blank">Confira tudo sobre os novos cursos aqui.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/08/13/pensou-php-pensou-especializa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSP &#8211; Java Server Pages ou Ja Se Phoi?</title>
		<link>http://especializa.com.br/blog/2010/07/07/jsp-java-server-pages-ou-ja-se-phoi/</link>
		<comments>http://especializa.com.br/blog/2010/07/07/jsp-java-server-pages-ou-ja-se-phoi/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 21:22:10 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[java ee]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[jsp]]></category>
		<category><![CDATA[servlets]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=207</guid>
		<description><![CDATA[Desde os tempos mais remotos, o JSP (Java Server Pages) sempre fez parte da especificação Java 2 Enterprise Edition (nossa conhecida J2EE 1.x). A idéia era simples: Servlets onde o foco for código Java, JSP onde o foco for HTML. A clássica divisão de responsabilidades entre designers e programadores.
Com a constante sugestão de alguns frameworks [...]]]></description>
			<content:encoded><![CDATA[<p>Desde os tempos mais remotos, o JSP (Java Server Pages) sempre fez parte da especificação Java 2 Enterprise Edition (nossa conhecida J2EE 1.x). A idéia era simples: Servlets onde o foco for código Java, JSP onde o foco for HTML. A clássica divisão de responsabilidades entre designers e programadores.</p>
<p>Com a constante sugestão de alguns frameworks MVC populares em usar outros engenhos de templates em detrimento do padrão JSP, como Velocity ou FreeMarker, e ainda, desde o Java EE 5.0, com a inserção do JSF, que nunca se deu muito bem com JSP, a pergunta foi, será que o JSP ficou obsoleto? Agora no Java EE 6.0, o Facelets virou padrão e a própria documentação oficial que saiu agora em Junho quase esqueceu de falar de JSP. Seria JSP <strong>J</strong>á <strong>S</strong>e <strong>P</strong>hoi? (E se foi com pê-agá).</p>
<p>Clica aí no leia mais pra gente discutir esse assunto.</p>
<p><span id="more-207"></span></p>
<p><em>N</em><em>o princípio era o verbo</em>, digo: <em>o socket</em>. Em nossas turmas de Java Developer, falamos sobre esse fundamento da programação distribuída. Como duas máquinas conseguem se comunicar em uma rede, preferencialmente via TCP/IP. Sempre acreditei que isso fosse interessante para quem ainda vai estudar Java para Web, porque podemos criar um exemplo construindo o browser e o servidor Web. Claro que o foco não é a reinvenção da roda, mas a discussão sobre a necessidade de um protocolo de comunicação que diga quem escreve e quem lê e qual o formato da escrita para que a comunicação se dê plenamente.</p>
<p>No Java Enterprise, existe a figura do servidor Web, como o nosso conhecido Apache Tomcat. A função dele é responder à onipresente outra figura que não necessariamente é escrita em Java, o browser, conhecendo plenamente o protocolo HTTP (obviamente que bem mais aprofundado do que no nosso curso Java Developer) e já entendendo que deve criar um objeto Java e chamar um método específico seu de acordo com a URL da requisição. Para os que já sabem disso, é aquela história do arquivo web.xml mapear um &lt;url-pattern&gt; para alguma &lt;servlet&gt; e a chamada ao método service() da servlet, que se for subclasse de HttpServlet, vai direcionar a requisição para um método como doGet(), doPost(), etc, de acordo com o método de requisição.</p>
<p>Para quem vem dessa linha, ou seja, quem aprendeu a programar em Java standalone, depois em rede, em rede com respostas concorrentes e finalmente caiu na Web, as Servlets são algo bem simples e interessante. No entanto, para quem aprendeu primeiro o HTML para criação de páginas estáticas, sabe como navegar na Internet e pretende tornar seu site mais dinâmico, ter que aprender Servlet pode não ser a coisa mais instigante da face da Terra.</p>
<p>O JSP entra justamente nessa lacuna. Fornecendo a capacidade de se escrever uma página HTML onde o programador (ou mesmo o designer) pode adicionar tags  &lt;% e %&gt; (e algumas variações que não vou entrar no mérito) e inserir assim conteúdo dinâmico à página. O problema é que mesmo quem nunca viu uma Servlet mais gorda na vida, vai acabar querendo escrever códigos de programação mais densos dentro dessas tags, conhecidas como scriptlets. O que vai acabar construindo um código que fora é HTML, dentro é Java. E esse Java acessa banco de dados, aplica regras de negócio, controla navegação, itera sobre resultados, enfim, faz tudo junto e misturado. Daí o termo código macarrônico.</p>
<p>Surgiram então soluções como JSP EL e JSTL que, juntas, dão mais cara de HTML e menos de Java aos códigos JSP e resolvendo detalhes como não precisar chamar get/sets dos objetos e misturar os escopos dos atributos setados na requisição, na sessão e na aplicação (engraçado, isso em PHP é visto como algo ruim, vai entender &#8230;).</p>
<p>O problema é que o JSP não se adequa muito bem ao mecanismo de alguns frameworks MVC e foi preterido pelos Struts I e II, por exemplo. Com JSF, a coisa foi ainda pior. O JSP não se encaixa no ciclo de vida de um componente JSF, o que torna as coisas mais lentas quando não dão erro. Um exemplo de erro é quando usamos a tag &lt;c:forEach&gt; do JSTL com tags JSF dentro. Se no interior dela inserirmos alguma tag com o atributo Id, a página não será renderizada quando houver mais de uma iteração da coleção varrida pelo &lt;c:forEach&gt;. No código abaixo:</p>
<pre class="brush: xml;">
&lt;c:forEach items=&quot;#{meuBean.itens}&quot; var=&quot;meuItem&quot;&gt;
    &lt;h:inputText id=&quot;elemento&quot; value=&quot;#{meuItem.nome}&quot;/&gt;
&lt;/c:forEach&gt;
</pre>
<p>Quando <em>itens</em>, uma coleção de qualquer coisa de <em>meuBean</em> tiver mais de um item adicionado, a página vai dar erro. Isso ocorre porque o JSP é processado antes. Quando chegar a fase JSF de renderização da página, o JSP terá sido executado e gerado duas linhas inputText com o mesmo id.</p>
<p>Já no código abaixo:</p>
<pre class="brush: xml;">
&lt;h:dataTable value=&quot;#{meuBean.itens}&quot; var=&quot;meuItem&quot;&gt;
    &lt;h:column&gt;
        &lt;h:inputText id=&quot;elemento&quot; value=&quot;#{meuItem.nome}&quot; /&gt;
    &lt;h:column&gt;
&lt;/h:dataTable&gt;
</pre>
<p>Refizemos a mesma coisa usando apenas tags JSF. Aqui, tudo é executado no mesmo momento, chegando apenas um id elemento.</p>
<p>Na nova documentação oficial do Java EE 6.0, há uma passagem no mínimo curiosa:</p>
<p>&#8220;<em>JSP is considered as a deprecated presentation technology for JavaServer Faces 2.0.</em>&#8221;</p>
<p>Claro, não estou negando o fato de que nem sempre você vai precisar do JSF. Nesses momentos o JSP pode lhe atender. Enfim, o que acho estranho é o fato de depois de grandes investimentos sobre o JSP ele estar sendo resumido a pequenos códigos uma vez que se vende o JSF para aplicações corporativas. Fica a dúvida sobre o que fazer quando utilizarmos JSP em um projeto mais simples que depois se torne um grande sistema. Devemos trocar todo o legado por JSF+Facelets, manter o JSP mesmo que menos integrado com o background corporativo gerando um custo de manutenção mais elevado ou misturar os dois e investir em uma combinação considerada oficialmente obsoleta?</p>
<p>Posso mudar de opinião amanhã, mas pra mim JSP Já Se Phoi.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 808px; width: 1px; height: 1px; overflow: hidden;">&lt;h:inputText id=&#8221;elemento&#8221;/&gt;&lt;h:inputText id=&#8221;elemento&#8221;/&gt;</div>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/07/07/jsp-java-server-pages-ou-ja-se-phoi/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Transacoes no PostgreSQL</title>
		<link>http://especializa.com.br/blog/2010/06/27/transacoes-no-postgresql/</link>
		<comments>http://especializa.com.br/blog/2010/06/27/transacoes-no-postgresql/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 03:39:44 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[tutoriais]]></category>
		<category><![CDATA[acid]]></category>
		<category><![CDATA[mvcc]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[transacoes]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=155</guid>
		<description><![CDATA[Prometi aos alunos da turma de PostgreSQL Developer do meu amigo Aercio que iria de tratar aqui do modelo de transações implementado no PostgreSQL. Como resolvi atualizar o material sobre PostgreSQL que venho escrevendo para a versão 9.0, decidi já testar os exemplos aqui no 9.0 beta 2 recém disponibilizado para download no site oficial. [...]]]></description>
			<content:encoded><![CDATA[<p>Prometi aos alunos da turma de PostgreSQL Developer do meu amigo Aercio que iria de tratar aqui do modelo de transações implementado no PostgreSQL. Como resolvi atualizar o material sobre PostgreSQL que venho escrevendo para a versão 9.0, decidi já testar os exemplos aqui no 9.0 beta 2 recém disponibilizado para download <a href="http://wwwmaster.postgresql.org/download/mirrors-ftp/source/v9.0beta2/postgresql-9.0beta2.tar.bz2" target="_blank">no site oficial</a>. Para uma ambientação inicial no PostgreSQL, não deixe de ler o primeiro capítulo do provável livro (ainda não atualizado) <a href="http://especializa.com.br/blog/2010/05/18/material-de-postgresql-administrator/" target="_blank">disponível por aqui</a>.<br />
<span id="more-155"></span><br />
<h2>O que são transações?</h2>
<p>Transações são conjuntos de instruções enviadas ao banco de dados que devem ser tratadas com uma única operação. Ou o servidor realiza tudo ou não realiza nada. O exemplo clássico usado em 110% dos cursos de bancos de dados é a famosa transação financeira de transferência de fundos. Imagine que Mônica deseje transferir 100,00 reais para a conta de Cebolinha. Esta operação na realidade se divide em duas. Um débito na conta de Mônica e um crédito de mesmo valor  na conta de Cebolinha (a ordem não interfere). Agora, se logo após o débito na primeira conta, o servidor sair do ar antes de que possa executar a segunda. Para onde foram os 100,00 reais?</p>
<p>Existem quatro características que os SGBDs devem garantir se pretendem lidar com transações com segurança. O conjunto dessas características é conhecido como ACID (atomicity, consistency, isolation, durability). Vejamos o que significam:</p>
<h3>Atomicidade</h3>
<p>É o ponto chave. É quem determina o tudo-ou-nada. A comunidade científica por longos anos acreditou que um átomo seria a unidade mínima da matéria, sólido e indivisível. Já se sabe em simples aulas de química que essa idéia caiu há séculos. No entanto, este conceito serve de analogia para ocasiões onde deve se considerar a impossibilidade de dividir algo em unidades menores.</p>
<p>Sendo assim, a atomicidade é a característica que torna um conjunto de operações um agrupamento indivisível executado por completo ou nada feito.</p>
<h3>Consistência</h3>
<p>Esta característica determina que o SGBD deve iniciar uma transação em um estado consistente e terminá-la deixando os dados em outro estado consistente. Caso alguma ação dentro de uma transação dê problemas e fira alguma regra de consistência de dados (como uma falha de escrita em disco, por exemplo), toda a transação deve ser completamente abortada, deixando os dados em seu estado consistente imediatamente anterior. O ato de abortar e voltar ao ponto inicial é conhecido como ROLLBACK.</p>
<p>Inconsistências não se resumem a problemas físicos de dados. É possível encarar uma situação fisicamente consistente como logicamente inconsistente. No exemplo dos desaparecimento dos 100,00 reais, o banco ficou em um estado inconsistente uma vez que se somarmos os saldos nas duas contas, independentemente do valor transferido os resultados pré e pós transferência deveria dar consistentemente o mesmo.</p>
<h3>Isolamento</h3>
<p>Esta característica remete a acessos concorrentes. Caso apenas uma transação seja executada no SGBD em determinado intervalo de tempo, o isolamento não vai lhe acrescentar nada. No entanto, como sabemos que SGBDs, na maioria dos casos, são usados por sistemas concorrentes, esta característica entra para garantir que informações de uma transação não se misturem com de outras.</p>
<p>Esta é a única característica relativa das quatro. Ou seja, é a única que não necessariamente é ruim quando infringida de alguma forma. Por um lado, seria ruim dados de uma transação estarem visíveis a outras como no problema clássico conhecido como Dirty Read que ocorre quando uma transação tx1 modifica alguns registros, uma transação tx2 ao selecionar alguns dados, visualiza esses registros alterados por tx1, mas esta primeira é abortada por alguma razão. Em resumo, tx2 leu dados errados, uma vez que eles nunca deveriam ter sido alterados.</p>
<p>Por outro lado, a capacidade de trabalhar com múltiplas transações ao mesmo tempo pode garantir o bom desempenho em sistemas muito acessados, uma vez que uma não fica esperando pela conclusão da outra. Elas são implementadas em ambientes multi-processos ou multi-threads e podem explorar melhor o pontencial multi-core dos hardwares atuais.</p>
<h3>Durabilidade</h3>
<p>Toda transação é encerrada com a execução da ação COMMIT. Esta característica é a garantia dada pelo SGBD que quando retornar um sinal COMMIT, os dados já devem estar gravados no meio persistente e ele deve ser capaz de recuperar esses dados em transações posteriores. Caso haja algum problema, a transação deve ser abortada. Conforme a regra da consistência, caso não haja problemas, o banco está jurando de pés juntos que gravou e você vai poder ler depois.</p>
<p>Como tratado no capítulo 1, o PostgreSQL escreve em disco registros de log WAL e assim que estejam completamente escritos, retorna o sinal COMMIT. Já no capítulo 2, tratamos das diretivas do postgresql.conf <em>fsync</em> e <em>wal_sync_method</em>. Para recapitular, a primeira faz com que o SGBD após a execução do comando de escrita do segmento WAL realize consultas ao sistema operacional a fim de obter a garantia de que o valor escrito está completamente descarregado no disco. Já a segunda determina o método adotado nesta pesquisa. Desligar a diretiva fsync pode proporcionar um maior desempenho, mas o risco da falta de durabilidade de uma transação &#8220;commitada&#8221; em geral não faz valer a pena esse tuning desesperado.</p>
<p>O método de sincronização com o disco de segmentos WAL (<em>wal_sync_method</em>) padrão do Linux é o <em>fdatasync</em>. O método <em>fsync</em> aguarda o sistema operacional descarregar em disco toda a pilha do buffer de I/O e atualizar o inode do sistema de arquivos com a informação de última alteração do arquivo escrito. O <em>fdatasync</em> não espera pela atualização deste metadado. Ele se preocupa apenas com o que mais importa que é a atualização propriamente dita dos dados.</p>
<h2>Transações e Write-ahead Logging</h2>
<p>Ao confirmar cada transação, o servidor não registra em disco as páginas de dados (aqueles 8Kb que ficam na memória). É bem menos custoso registrar neste momento (e esperar pelo fsync), um registro de segmento WAL uma vez que ele é linear (alterações na base real podem envolver dados que não necessariamente estejam na mesma página de dados) e por isso realizam movimentos menores da controladora de disco, além de não requerer pesquisa por espaço livre (FSM).</p>
<p>Por outro lado, a manipulação das páginas de memória compartilhada que são carregadas do e para o disco é bem mais vantajoso do que sair vasculhando registros de log de operações a fim de obter os dados necessários nas consultas.</p>
<p>Sendo assim, o PostgreSQL precisa realizar essa tradução do que é salvo em log para as páginas de dados de tempos em tempos. Este processo de escrita em background (bgwriter) é denominado CHECKPOINT. No PostgreSQL, checkpoints não têm ligação direta com o COMMIT de uma transação, mas achei interessante ilustrar o que deve ocorrer com algumas transações confirmadas entre um checkpoint e um provável crash da base.</p>
<p>O vídeo abaixo mostra o que ocorre com 5 transações considerando que em um momento distinto haverá uma ação de checkpoint e posteriormente haverá um crash do servidor, provocando sua queda inesperada. Caso você não consiga ver o vídeo, clique para baixá-lo em <a href="http://www.especializa.com.br/blog/wp-content/uploads/2010/06/transacoes.ogv">Ogv</a> (theora) ou <a href="http://www.especializa.com.br/blog/wp-content/uploads/2010/06/transacoes.mp4">MP4</a> (H.264).<br />
<video width="500" height="375" controls><br />
<source src="http://www.especializa.com.br/blog/wp-content/uploads/2010/06/transacoes.ogv"/><br />
<source src="http://www.especializa.com.br/blog/wp-content/uploads/2010/06/transacoes.mp4"/><br />
Seu browser não suporta vídeos HTML5. Operamor de Deus, chreima ele no firefoxgo.<br />
</video></p>
<h2>Problemas de isolamento</h2>
<p>Transações já são interessantes mesmo em cenário standalone, uma vez que é possível desfazer todo um bloco de procedimentos apenas com um simples Rollback. Mas é em sistemas concorrentes que o bicho pega. Caso o isolamento não seja garantido alguns problemas podem ocorrer.</p>
<h3>Dirty read</h3>
<p>O primeiro deles já foi apontado. Dirty Read ou leitura suja acontece quando uma transação lê algum dado alterado por outra que acaba não confirmando suas alterações. É um problema extremo que de fato não é comum que bancos de dados permitam que ocorra. O PostgreSQL não permite. Confira no exercício abaixo. Primeiramente, vamos criar a base para os testes:</p>
<pre class="brush: sql;">

postgres=# CREATE DATABASE exercicio;
CREATE DATABASE
postgres=# \c exercicio
You are now connected to database &quot;exercicio&quot;.
exercicio=# create table aluno (id serial primary key, nome varchar(50));
NOTICE:  CREATE TABLE will create implicit sequence &quot;aluno_id_seq&quot; for serial column &quot;aluno.id&quot;
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index &quot;aluno_pkey&quot; for table &quot;aluno&quot;
CREATE TABLE
exercicio=# INSERT into aluno (nome) values ('Huguinho'), ('Zezinho'), ('Luisinho'), ('Juquinha'), ('Joaozinho');
INSERT 0 5
</pre>
<p>Criamos 5 alunos (só peça boa =) em uma nova base. Agora vamos ao primeiro cenário. Para isto será necessário que você abra duas instâncias do psql ou qualquer outra ferramenta cliente (que certamente não será tão limpa e cheirosa quanto o psql).</p>
<p>Inicie uma transação em cada uma executando em ambas a instrução:</p>
<pre class="brush: sql;">

exercicio=# begin;
BEGIN
</pre>
<p>Na primeira, execute o seguinte comando:</p>
<pre class="brush: sql;">

exercicio=# UPDATE aluno set nome = 'Jose da Silva' where id = 2;
UPDATE 1

exercicio=# select * from aluno;
id |     nome
----+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
(5 rows)
</pre>
<p>Veja que o nome de Zezinho agora é Jose da Silva.</p>
<p>Realize a mesma consulta na segunda instância do psql:</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |   nome
----+-----------
1 | Huguinho
2 | Zezinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
(5 rows)
</pre>
<p>Como você atentou, os alunos continuam com seus nomes intactos. O que a primeira transação modificou não foi sentido pela segunda. O motivo é que se a primeira voltar atrás, a segunda já teria lido e tomado suas próprias decisões baseando-se em dados inconsistentes. Confira como faríamos para reverter (execute na primeira transação):</p>
<pre class="brush: sql;">

exercicio=# ROLLBACK ;
ROLLBACK
exercicio=# select * from aluno;
id |   nome
----+-----------
1 | Huguinho
2 | Zezinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
(5 rows)
</pre>
<p>Nossa base voltou ao estágio em que estava no momento do BEGIN.</p>
<h3>Unrepeatable Reads</h3>
<p>Leituras não repetíveis acontecem quando uma transação lê algum dado em determinado momento, posteriormente outra transação altera ou deleta e executa o COMMIT. A primeira volta a ler os mesmos dados e constata que eles não estão mais como antes. Este não chega a ser um problema em muitos sistemas, a ponto do PostgreSQL, em seu nível de isolamento padrão, permitir que ocorra. Vejamos:</p>
<p>PSQL1: Iniciamos uma nova transação (aquela anterior foi desfeita com ROLLBACK) e atualizamos novamente o nome de Zezinho.</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# UPDATE aluno set nome = 'Jose da Silva' where id = 2;
UPDATE 1
</pre>
<p>PSQL2: Como visto antes, nada foi percebido pela outra transação.</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |   nome
---+-----------
1 | Huguinho
2 | Zezinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
(5 rows)
</pre>
<p>PSQL1: Confirmamos a alteração</p>
<pre class="brush: sql;">

exercicio=# COMMIT ;
COMMIT
</pre>
<p>PSQL2: Agora a alteração foi sentida</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |     nome
---+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
(5 rows)
</pre>
<h3>Phantom Read</h3>
<p>O problema das leituras fantasmas é parecido com o das leituras não repetíveis, o que muda é que uma das transações em vez de alterar o conjunto de dados, insere um dado novo.</p>
<p>Vamos refazer a dinâmica. Primeiramente, encerre as transações das duas instâncias do psql. Neste momento, tanto faz encerrar com COMMIT ou com ROLLBACK. Se a transação não estiver em curso, você receberá uma mensagem como esta:</p>
<pre>WARNING:  there is no transaction in progress</pre>
<p>PSQL1: Inicie a transação e insira duas novas alunas</p>
<pre class="brush: sql;">

# begin;
BEGIN
exercicio=# INSERT INTO aluno (nome) values ('Chiquinha'), ('Mariazinha');
INSERT 0 2
</pre>
<p>PSQL2: Inicie a transação e consulte a lista de alunos</p>
<pre class="brush: sql;">

# begin;
BEGIN
exercicio=# select * from aluno;
id |     nome
----+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
(5 rows)
</pre>
<p>Ninguém novo até agora.</p>
<p>PSQL1: Confirme sua transação com um COMMIT</p>
<pre class="brush: sql;">

exercicio=# COMMIT ;
COMMIT
</pre>
<p>PSQL2: Veja que as novas alunas agora estão presentes</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |     nome
----+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
6 | Chiquinha
7 | Mariazinha
(7 rows)
</pre>
<h2>Níveis de isolamento</h2>
<p>Existem quatro níveis de isolamento segundo o padrão SQL:</p>
<h3>READ UNCOMMITED</h3>
<p>Nível menos isolado. Aqui, todos os problemas citados podem ocorrer, inclusive as porcas dirty reads. É muito difícil um SGBD permitir que o DBA mesmo que deliberadamente configure o nível de isolamento para READ UNCOMMITED. Em resumo, é um nível acadêmico, apenas para você dizer que conhece.</p>
<h3>READ COMMITED</h3>
<p>Nível padrão do PostgreSQL. Aqui dirty reads estão barradas, mas, como verificamos nos exercícios anteriores, unrepeatable reads e phantom reads podem ocorrer.</p>
<h3>REPEATABLE READ</h3>
<p>Neste nível, apenas as phantom reads podem ocorrer. Os SGBDs fazem bloqueio (lock) do conjunto de dados lidos em uma transação, o que evita que as leituras posteriores apresentem resultados modificados ou deletados confirmados por outra transação. No entanto, não há como fazer lock de um registro que ainda não existia na primeira leitura. Este é o motivo pelo qual as leituras fantasmas podem assombrar por aqui.</p>
<h3>SERIALIZABLE</h3>
<p>Esse é o nível que leva o isolamento ao máximo. Aqui, nenhum desses problemas podem ocorrer.</p>
<h3>Em resumo:</h3>
<p>A tabela abaixo mostra os níveis de isolamento em relação aos problemas que podem ou não provocar.</p>
<table class="CALSTABLE" border="1">
<col></col>
<col></col>
<col></col>
<col></col>
<thead>
<tr>
<th>Nível de isolamento</th>
<th>Dirty Read</th>
<th>Nonrepeatable Read</th>
<th>Phantom Read</th>
</tr>
</thead>
<tbody>
<tr>
<td>Read uncommitted</td>
<td>Possível</td>
<td>Possível</td>
<td>Possível</td>
</tr>
<tr>
<td>Read committed</td>
<td>Impossível</td>
<td>Possível</td>
<td>Possível</td>
</tr>
<tr>
<td>Repeatable read</td>
<td>Impossível</td>
<td>Impossível</td>
<td>Possível</td>
</tr>
<tr>
<td>Serializable</td>
<td>Impossível</td>
<td>Impossível</td>
<td>Impossível</td>
</tr>
</tbody>
</table>
<p>Para modificar o nível de isolamento da transação corrente, existe o comando SET TRANSACTION que deve ser executado logo após o BEGIN e antes de qualquer consulta SELECT, INSERT, DELETE, UPDATE, FETCH ou COPY. Este comando possui o seguinte formato:</p>
<p>SET TRANSACTION [ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } ]  [ {READ WRITE | READ ONLY} ]</p>
<p>Com ele, é possível determinar o nível de isolamento, escrevendo ISOLATION LEVEL seguido por algum dos níveis já apresentados e/ou informar as opções READ WRITE (padrão) ou READ ONLY. Transações READ ONLY (somente leitura) não podem alterar nenhuma tabela que não seja temporária.</p>
<p>Vamos a um exemplo:</p>
<pre class="brush: sql;">

exercicio=# begin;
BEGIN
exercicio=# set transaction read only;
SET
exercicio=# UPDATE aluno SET nome = 'teste';
ERROR:  cannot execute UPDATE in a read-only transaction
exercicio=# select * from aluno;
ERROR:  current transaction is aborted, commands ignored until end of transaction block
exercicio=# rollback;
ROLLBACK
</pre>
<p>Após o BEGIN, determinamos que nossa transação seria somente leitura. Logo após, tentamos infringir o determinado em SET TRANSACTION executando um UPDATE qualquer. Confira o erro resultante. Segui adiante para mostrar algo que ainda não havia falado, mas ocorre sempre que uma instrução retorna erro dentro de uma transação. Qualquer nova instrução retorna o erro informando que a transação foi abortada. Cabe-nos apenas executar o ROLLBACK para encerrar a transação problemática.</p>
<p>O nível de isolamento REPEATABLE READ no PostgreSQL é encarado como um  SERIALIZABLE, ou seja, não permite leituras fantasmas. Vejamos:</p>
<p>PSQL1: Determinando o nível de isolamento para REPEATABLE READ, que no PostgreSQL funciona como um SERIALIZABLE</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# SET transaction ISOLATION LEVEL REPEATABLE READ ;
SET
exercicio=# select * from aluno;
 id |     nome
----+---------------
 1 | Huguinho
 3 | Luisinho
 4 | Juquinha
 5 | Joaozinho
 2 | Jose da Silva
 6 | Chiquinha
 7 | Mariazinha
(7 rows)
</pre>
<p>PSQL2: Inserindo um novo aluno e confirmando a transação</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# INSERT INTO aluno (nome) values ('Maradona');
INSERT 0 1
exercicio=# COMMIT ;
</pre>
<p>PSQL1: Olha aí que Maradona ainda não foi inserido e não é porque ele é argentino. Após a confirmação deste transação, ele vai aparecer. Só espero que não estrague a festa.</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
 id |     nome
----+---------------
 1 | Huguinho
 3 | Luisinho
 4 | Juquinha
 5 | Joaozinho
 2 | Jose da Silva
 6 | Chiquinha
 7 | Mariazinha
(7 rows)

exercicio=# COMMIT ;
COMMIT
exercicio=# select * from aluno;
 id |     nome
----+---------------
 1 | Huguinho
 3 | Luisinho
 4 | Juquinha
 5 | Joaozinho
 2 | Jose da Silva
 6 | Chiquinha
 7 | Mariazinha
 8 | Maradona
(8 rows)
</pre>
<p>O nível de isolamento READ UNCOMMITED é encarado como um READ COMMITED (o padão). Assim, leituras sujas jamais são permitidas, no PostgreSQL.</p>
<h2>Controle de versão</h2>
<p>Ao contrário de alguns bancos de dados, o PostgreSQL por padrão trabalha com controle de versão ao invés de bloqueio de dados na manipulação de transações. Este mecanismo, conhecido como MVCC (multi-version concurrency control) costuma ser bem mais eficiente em termos de desempenho em comparação aos bloqueios de registros que já são bem melhores do que os bloqueios de tabelas. Além do PostgreSQL, bancos como Oracle, Firebird, HiperSonic, SyBase, ZODB, entre outros também se baseiam no MVCC para controle de isolamento de transações.</p>
<p>Para cada registro de cada tabela sempre existem dois campos utilizados  no controle de transações. O campo xmin informa o id (auto-sequenciado)  da transação que gerou este registro. Já xmax determina o id da  transação que a deletou ou alterou seu conteúdo, gerando um novo  registro com xmin atualizado. Para ilustrar como funciona o controle, vejamos o exemplo:</p>
<p>PSQL1:</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# select *, xmin, xmax from aluno;
id |     nome      | xmin | xmax
---+---------------+------+------
 1 | Huguinho      |  664 |    0
 3 | Luisinho      |  664 |    0
 4 | Juquinha      |  664 |    0
 5 | Joaozinho     |  664 |    0
 2 | Jose da Silva |  668 |    0
 6 | Chiquinha     |  669 |    0
 7 | Mariazinha    |  669 |    0
 8 | Maradona      |  670 |    0
(8 rows)

exercicio=# DELETE FROM aluno WHERE nome = 'Maradona';
DELETE 1
exercicio=# select *, xmin, xmax from aluno;
 id |     nome      | xmin | xmax
----+---------------+------+------
 1 | Huguinho      |  664 |    0
 3 | Luisinho      |  664 |    0
 4 | Juquinha      |  664 |    0
 5 | Joaozinho     |  664 |    0
 2 | Jose da Silva |  668 |    0
 6 | Chiquinha     |  669 |    0
 7 | Mariazinha    |  669 |    0
(7 rows)
exercicio=# UPDATE aluno SET nome = 'Zezinho' where id = 2;
UPDATE 1
exercicio=# select *, xmin, xmax from aluno;
 id |    nome    | xmin | xmax
----+------------+------+------
 1 | Huguinho   |  664 |    0
 3 | Luisinho   |  664 |    0
 4 | Juquinha   |  664 |    0
 5 | Joaozinho  |  664 |    0
 6 | Chiquinha  |  669 |    0
 7 | Mariazinha |  669 |    0
 2 | Zezinho    |  671 |    0
(7 rows)
</pre>
<p>No primeiro SELECT, podemos visualizar o xmin de cada registro. Perceba que Jose da Silva possui um xmin maior do que os outros alunos que foram inseridos no mesmo momento. Isto se deve aos UPDATEs que executamos nos exemplos posteriores ao primeiro INSERT.</p>
<p>Realizamos um DELETE para excluir Maradona de onde ele não foi chamado. O SELECT posterior não tem como vê-lo uma vez que o xmax é justamente o id da transação atual. Após um UPDATE para voltarmos com o nome Zezinho do aluno 2, e eis que surgiu um registro no fim da fila com id de transação maior do que todos. O registro com Jose da Silva também não está mais visível aqui.</p>
<p>Agora vamos a uma outra transação antes de confirmação as alterações na atual.</p>
<p>PSQL2: Selecionando os registros em outra transação antes do COMMIT da anterior</p>
<pre class="brush: sql;">

exercicio=# SELECT *, xmin, xmax FROM aluno;
 id |     nome      | xmin | xmax
----+---------------+------+------
 1 | Huguinho      |  664 |    0
 3 | Luisinho      |  664 |    0
 4 | Juquinha      |  664 |    0
 5 | Joaozinho     |  664 |    0
 2 | Jose da Silva |  668 |  671
 6 | Chiquinha     |  669 |    0
 7 | Mariazinha    |  669 |    0
 8 | Maradona      |  670 |  671
(8 rows)
</pre>
<p>Nela, é possível visualizar os xmax de Jose da Silva e Maradona com o valor da transação em PSQL1. Como a primeira ainda não confirmou a transação, ainda não estamos vendo os novos valores aqui (só veríamos se o nível de isolamento fosse READ UNCOMMITED, que permite dirty reads e não é suportado pelo PostgreSQL).</p>
<p>Vamos confirmar e visualizar o resultado final:</p>
<p>PSQL1: Confirmação e visualização do resultado</p>
<pre class="brush: sql;">

exercicio=# COMMIT ;
COMMIT
exercicio=# select *, xmin, xmax from aluno;
 id |    nome    | xmin | xmax
----+------------+------+------
 1 | Huguinho   |  664 |    0
 3 | Luisinho   |  664 |    0
 4 | Juquinha   |  664 |    0
 5 | Joaozinho  |  664 |    0
 6 | Chiquinha  |  669 |    0
 7 | Mariazinha |  669 |    0
 2 | Zezinho    |  671 |    0
(7 rows)
</pre>
<p>PSQL2: Visualização atualizada. Se estivesse no nível de isolamento SERIALIZABLE ou REPEATABLE READ, não seria possível ver os registros atualizados e deletados.</p>
<pre class="brush: sql;">

exercicio=# SELECT *, xmin, xmax FROM aluno;
id |    nome    | xmin | xmax
----+------------+------+------
1 | Huguinho   |  664 |    0
3 | Luisinho   |  664 |    0
4 | Juquinha   |  664 |    0
5 | Joaozinho  |  664 |    0
6 | Chiquinha  |  669 |    0
7 | Mariazinha |  669 |    0
2 | Zezinho    |  671 |    0
(7 rows)
</pre>
<h2>MVCC e a necessidade de Vacuum</h2>
<p>O MVCC traz uma série de benefícios sobre os bloqueios:</p>
<ul>
<li>Processos de leitura não bloqueiam processos de escrita e vice-versa</li>
<li>Praticamente elimina a incidência de contenções de transações</li>
<li>Reduz drasticamente o risco de DEAD LOCK</li>
<li>Possui um desempenho bem superior</li>
</ul>
<p>Mas também é possível detectar um ponto fraco no MVCC. Os registros alterados e excluídos não ficam mais acessíveis mas não são imediatamente riscados do mapa. Ou seja, continuam inchando o disco. Para evitar que o banco tome proporções além do aceitável (este aceitável é bem relativo), execute regularmente (este regularmente é mais relativo ainda) a instrução VACUUM, que além de apagar os registros (VACUUM FULL) ou simplesmente apontando nas páginas de dados como área disponível para ser sobrescrita (VACUUM simples), também atualiza o ID das transações para evitar estouro e consequente reinício automático dos IDs de transações, o que poderia proporcionar resultados catrastróficos (como uma espécie de bug do milênio).</p>
<p>Como os IDs das transações são inteiros de 32 bits, a cada 4 bilhões lá vai fumaça de transações, isto poderá ocorrer. Voltaremos a este assunto em uma seção específica para o comando VACUUM, nos policiando para não realizar mais de 4 bilhões de exemplos daqui até lá.</p>
<h2>Bloqueios e deadlocks</h2>
<p>Provavelmente, você não irá precisar trabalhar com bloqueios explícitos no PostgreSQL, mas existem situações onde podem ser úteis. A prova é que o PostgreSQL implicitamente trabalha com bloqueios em algumas instruções. Pra variar, vamos a um exemplo:</p>
<p>PSQL1: Atualizando o nome de Mariazinha</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# UPDATE aluno SET nome = 'Maria Francisca' where id = 7;
UPDATE 1
</pre>
<p>PSQL2: Atualizando os nomes de Chiquinha e Mariazinha em outra transação</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# UPDATE aluno SET nome = 'Francisca' where id = 6;
UPDATE 1

exercicio=# UPDATE aluno SET nome = 'Maria Joaquina' where id = 7;
</pre>
<p>Até o primeiro UPDATE, fora o dilúvio que se abateu sobre Recife e o temporal do lado de fora da janela, estava tudo normal. No segundo, a chuva até que diminuiu, mas a alteração do nome de Mariazinha ficou congelada (bloqueada) até que o PSQL1 confirme a sua alteração. Caso não ficasse, a transação que encerrasse primeiro teria suas  alterações perdidas devido a outra que encerrasse depois, independentemente de quem realizou o UPDATE primeiro. Isto  resultaria em um outro problema de isolamento conhecido por Lost  Update, que pode ainda ser mais grave se uma transação precisar dos dados da outra para atualizar os seus, como eles não estarão disponíveis até o COMMIT, o estado final potencialmente deverá ferir o princípio da consistência.</p>
<p>Agora vamos voltar à primeira transação não para confirmar a alteração e liberar o UPDATE na segunda, mas para pôr mais lenha na fogueira e também esperar pela segunda devido a alteração do nome de Chiquinha.</p>
<p>PSQL1: Atualizando um registro já modificado pela outra transação</p>
<pre class="brush: sql;">

exercicio=# UPDATE aluno SET nome = 'Chica' where id = 6;

ERROR:  deadlock detected
DETAIL:  Process 9019 waits for ShareLock on transaction 674; blocked by process 8919.
Process 8919 waits for ShareLock on transaction 676; blocked by process 9019.
Process 9019: UPDATE aluno SET nome = 'Maria Joaquina' where id = 7;
Process 8919: UPDATE aluno SET nome = 'Chica' where id = 6;
HINT:  See server log for query details.
</pre>
<p>Booom, DEAD LOCK. Game over. Façamos um breve parênteses para a mensagem de erro do PostgreSQL que não é uma simples mensagem, é uma aula sobre o assunto. Como sei que você é uma pessoa bastante atenta, posso apostar que percebeu o termo ShareLock da mensagem de erro acima. Ela significa bloqueio compartilhado.</p>
<p>Antes de seguir adiante, façamos mais uma dinâmica a fim de colher informações do PostgreSQL acerca dos bloqueios realizados implícita ou explicitamente em determinado momento. A view de catálogo pg_locks recupera os locks gerenciados no momento pelo pelo servidor. Unindo ela com as tabelas de catálogo pg_class e pg_database podemos ter uma informação bem interessante:</p>
<p>PSQL1: Iniciando uma inofensiva transação para mais uma vez alterar o nome de Chiquinha e consultando o bloqueio gerado</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# UPDATE aluno SET nome = 'Chica' where id = 6;
UPDATE 1

exercicio=# select l.locktype, l.mode, l.pid, d.datname, c.relname from pg_locks l inner join pg_database d on l.database = d.oid inner join pg_class c on l.relation = c.oid where c.relkind = 'r' and relname not like 'pg_%';
locktype |       mode       | pid  |  datname  | relname
----------+------------------+------+-----------+---------
relation | RowExclusiveLock | 8919 | exercicio | aluno
(1 row)
</pre>
<p>O PostgreSQL reconhece oito tipos de bloqueios: ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE.</p>
<p>É possível solicitar explicitamente um bloqueio sobre tabelas ou mesmo registros através do comando Lock:</p>
<pre class="brush: sql;">

exercicio=# \h LOCK
Command:     LOCK
Description: lock a table
Syntax:
LOCK [ TABLE ] [ ONLY ] name [, ...] [ IN lockmode MODE ] [ NOWAIT ]

where lockmode is one of:

ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
| SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
</pre>
<h3>Access Share</h3>
<p>Bloqueio requerido apenas por instruções SELECT e ANALYZE são simples leitura em geral permitidas, a menos que alguma outra transação tenha requerido Access Exclusive.</p>
<h3>Row Share</h3>
<p>A instrução SELECT com a cláusula FOR UPDATE obtém este nível de bloqueio. Ele conflita apenas com os níveis mais retritos Exclusive e Access Exclusive.</p>
<h3>Row Exclusive</h3>
<p>Bloqueio solicitado automaticamente por instruções INSERT, UPDATE, DELETE. Conflita com quem precisar além de Access Exclusive e Exclusive, também com Share Row Exclusive e Share.</p>
<h3>Share Update Exclusive</h3>
<p>Bloqueio padrão do comando VACUUM sem a opção FULL. Conflita com todos os próximos níveis de bloqueio e com ele próprio. Bloqueia a tabela inteira.</p>
<h3>Share</h3>
<p>A partir deste nível de bloqueio, já vimos com quem cada um conflita. Bloqueia toda a tabela e é requerido por instruções CREATE INDEX.</p>
<h3>Share Row Exclusive</h3>
<p>Similar ao Exclusive, mas apenas no nível de linha. Não há instrução SQL que automaticamente solicite este nível de bloqueio.</p>
<h3>Exclusive</h3>
<p>Este só não conflita com Access Share. É requerido automaticamente apenas em tabelas de catálogo em determinadas operações.</p>
<h3>Access Exclusive</h3>
<p>Conflita com todo mundo. Ou seja, nenhuma outra transação pode operar na mesma tabela bloqueada por alguma transação que solicitou Access Exclusive. Instruções ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER e VACUUM FULL necessitam deste modo de bloqueio.</p>
<h2>Conclusão</h2>
<p>Percebeu como é denso e fundamental o assunto <em>transações</em>? Elas são provavelmente o mais frequente motivo para desenvolvedores optarem por trabalhar com SGBDs em vez de persistirem dados diretamente em arquivos.</p>
<p>Acredito que tanto DBAs quanto desenvolvedores precisam conhecer bem como o SGBD escolhido lida com elas e optar pelo PostgreSQL é optar pelo que há de mais avançado no mercado sobre o assunto.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 9880px; width: 1px; height: 1px; overflow: hidden;">
<p>Prometi aos alunos da turma de PostgreSQL Developer do meu amigo  Aercio que iria de tratar aqui do modelo de transações implementado no  PostgreSQL. Como resolvi atualizar o material sobre PostgreSQL que venho  escrevendo para a versão 9.0, decidi já testar os exemplos aqui no 9.0  beta 2 recém disponibilizado para download <a href="http://wwwmaster.postgresql.org/download/mirrors-ftp/source/v9.0beta2/postgresql-9.0beta2.tar.bz2" target="_blank">no site oficial</a>. Para uma ambientação inicial no  PostgreSQL, não deixe de ler o primeiro capítulo do provável livro  (ainda não atualizado) <a href="http://especializa.com.br/blog/2010/05/18/material-de-postgresql-administrator/" target="_blank">disponível por aqui</a>.</p>
<h2><!--more-->O que são  transações?</h2>
<p>Transações são conjuntos de instruções enviadas ao banco de dados que  devem ser tratadas com uma única operação. Ou o servidor realiza tudo  ou não realiza nada. O exemplo clássico usado em 110% dos cursos de  bancos de dados é a famosa transação financeira de transferência de  fundos. Imagine que Mônica deseje transferir 100,00 reais para a conta  de Cebolinha. Esta operação na realidade se divide em duas. Um débito na  conta de Mônica e um crédito de mesmo valor  na conta de Cebolinha (a  ordem não interfere). Agora, se logo após o débito na primeira conta, o  servidor sair do ar antes de que possa executar a segunda. Para onde  foram os 100,00 reais?</p>
<p>Existem quatro características que os SGBDs devem garantir se  pretendem lidar com transações com segurança. O conjunto dessas  características é conhecido como ACID (atomicity, consistency,  isolation, durability). Vejamos o que significam:</p>
<h3>Atomicidade</h3>
<p>É o ponto chave. É quem determina o tudo-ou-nada. A comunidade  científica por longos anos acreditou que um átomo seria a unidade mínima  da matéria, sólido e indivisível. Já se sabe em simples aulas de  química que essa idéia caiu há séculos. No entanto, este conceito serve  de analogia para ocasiões onde deve se considerar a impossibilidade de  dividir algo em unidades menores.</p>
<p>Sendo assim, a atomicidade é a característica que torna um conjunto  de operações um agrupamento indivisível executado por completo ou nada  feito.</p>
<h3>Consistência</h3>
<p>Esta característica determina que o SGBD deve iniciar uma transação  em um estado consistente e terminá-la deixando os dados em outro estado  consistente. Caso alguma ação dentro de uma transação dê problemas e  fira alguma regra de consistência de dados (como uma falha de escrita em  disco, por exemplo), toda a transação deve ser completamente abortada,  deixando os dados em seu estado consistente imediatamente anterior. O  ato de abortar e voltar ao ponto inicial é conhecido como ROLLBACK.</p>
<p>Inconsistências não se resumem a problemas físicos de dados. É  possível encarar uma situação fisicamente consistente como logicamente  inconsistente. No exemplo dos desaparecimento dos 100,00 reais, o banco  ficou em um estado inconsistente uma vez que se somarmos os saldos nas  duas contas, independentemente do valor transferido os resultados pré e  pós transferência deveria dar consistentemente o mesmo.</p>
<h3>Isolamento</h3>
<p>Esta característica remete a acessos concorrentes. Caso apenas uma  transação seja executada no SGBD em determinado intervalo de tempo, o  isolamento não vai lhe acrescentar nada. No entanto, como sabemos que  SGBDs, na maioria dos casos, são usados por sistemas concorrentes, esta  característica entra para garantir que informações de uma transação não  se misturem com de outras.</p>
<p>Esta é a única característica relativa das quatro. Ou seja, é a única  que não necessariamente é ruim quando infringida de alguma forma. Por  um lado, seria ruim dados de uma transação estarem visíveis a outras  como no problema clássico conhecido como Dirty Read que ocorre quando  uma transação tx1 modifica alguns registros, uma transação tx2 ao  selecionar alguns dados, visualiza esses registros alterados por tx1,  mas esta primeira é abortada por alguma razão. Em resumo, tx2 leu dados  errados, uma vez que eles nunca deveriam ter sido alterados.</p>
<p>Por outro lado, a capacidade de trabalhar com múltiplas transações ao  mesmo tempo pode garantir o bom desempenho em sistemas muito acessados,  uma vez que uma não fica esperando pela conclusão da outra. Elas são  implementadas em ambientes multi-processos ou multi-threads e podem  explorar melhor o pontencial multi-core dos hardwares atuais.</p>
<h3>Durabilidade</h3>
<p>Toda transação é encerrada com a execução da ação COMMIT. Esta  característica é a garantia dada pelo SGBD que quando retornar um sinal  COMMIT, os dados já devem estar gravados no meio persistente e ele deve  ser capaz de recuperar esses dados em transações posteriores. Caso haja  algum problema, a transação deve ser abortada. Conforme a regra da  consistência, caso não haja problemas, o banco está jurando de pés  juntos que gravou e você vai poder ler depois.</p>
<p>Como tratado no capítulo 1, o PostgreSQL escreve em disco registros  de log WAL e assim que estejam completamente escritos, retorna o sinal  COMMIT. Já no capítulo 2, tratamos das diretivas do postgresql.conf <em>fsync</em> e <em>wal_sync_method</em>. Para recapitular, a primeira faz com que o  SGBD após a execução do comando de escrita do segmento WAL realize  consultas ao sistema operacional a fim de obter a garantia de que o  valor escrito está completamente descarregado no disco. Já a segunda  determina o método adotado nesta pesquisa. Desligar a diretiva fsync  pode proporcionar um maior desempenho, mas o risco da falta de  durabilidade de uma transação &#8220;commitada&#8221; em geral não faz valer a pena  esse tuning desesperado.</p>
<p>O método de sincronização com o disco de segmentos WAL (<em>wal_sync_method</em>)  padrão do Linux é o <em>fdatasync</em>. O método <em>fsync</em> aguarda o  sistema operacional descarregar em disco toda a pilha do buffer de I/O e  atualizar o inode do sistema de arquivos com a informação de última  alteração do arquivo escrito. O <em>fdatasync</em> não espera pela  atualização deste metadado. Ele se preocupa apenas com o que mais  importa que é a atualização propriamente dita dos dados.</p>
<h2>Transações e Write-ahead Logging</h2>
<p>Ao confirmar cada transação, o servidor não registra em disco as  páginas de dados (aqueles 8Kb que ficam na memória). É bem menos custoso  registrar neste momento (e esperar pelo fsync), um registro de segmento  WAL uma vez que ele é linear (alterações na base real podem envolver  dados que não necessariamente estejam na mesma página de dados) e por  isso realizam movimentos menores da controladora de disco, além de não  requerer pesquisa por espaço livre (FSM).</p>
<p>Por outro lado, a manipulação das páginas de memória compartilhada  que são carregadas do e para o disco é bem mais vantajoso do que sair  vasculhando registros de log de operações a fim de obter os dados  necessários nas consultas.</p>
<p>Sendo assim, o PostgreSQL precisa realizar essa tradução do que é  salvo em log para as páginas de dados de tempos em tempos. Este processo  de escrita em background (bgwriter) é denominado CHECKPOINT. No  PostgreSQL, checkpoints não têm ligação direta com o COMMIT de uma  transação, mas achei interessante ilustrar o que deve ocorrer com  algumas transações confirmadas entre um checkpoint e um provável crash  da base.</p>
<p>O vídeo abaixo mostra o que ocorre com 5 transações considerando que  em um momento distinto haverá uma ação de checkpoint e posteriormente  haverá um crash do servidor, provocando sua queda inesperada. Caso você  não consiga ver o vídeo, clique para baixá-lo em <a href="http://www.especializa.com.br/blog/wp-content/uploads/2010/06/transacoes.ogv">Ogv</a> (theora) ou <a href="http://www.especializa.com.br/blog/wp-content/uploads/2010/06/transacoes.mp4">MP4</a> (H.264).</p>
<p>Seu browser não suporta vídeos HTML5. Operamor de Deus, chreima ele  no firefoxgo.</p>
<h2>Problemas de isolamento</h2>
<p>Transações já são interessantes mesmo em cenário standalone, uma vez  que é possível desfazer todo um bloco de procedimentos apenas com um  simples Rollback. Mas é em sistemas concorrentes que o bicho pega. Caso o  isolamento não seja garantido alguns problemas podem ocorrer.</p>
<h3>Dirty read</h3>
<p>O primeiro deles já foi apontado. Dirty Read ou leitura suja acontece  quando uma transação lê algum dado alterado por outra que acaba não  confirmando suas alterações. É um problema extremo que de fato não é  comum que bancos de dados permitam que ocorra. O PostgreSQL não permite.  Confira no exercício abaixo. Primeiramente, vamos criar a base para os  testes:</p>
<pre class="brush: sql;">

postgres=# CREATE DATABASE exercicio;
CREATE DATABASE
postgres=# \c exercicio
You are now connected to database &quot;exercicio&quot;.
exercicio=# create table aluno (id serial primary key, nome varchar(50));
NOTICE:  CREATE TABLE will create implicit sequence &quot;aluno_id_seq&quot; for serial column &quot;aluno.id&quot;
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index &quot;aluno_pkey&quot; for table &quot;aluno&quot;
CREATE TABLE
exercicio=# INSERT into aluno (nome) values ('Huguinho'), ('Zezinho'), ('Luisinho'), ('Juquinha'), ('Joaozinho');
INSERT 0 5
</pre>
<p>Criamos 5 alunos (só peça boa =) em uma nova base. Agora vamos ao  primeiro cenário. Para isto será necessário que você abra duas  instâncias do psql ou qualquer outra ferramenta cliente (que certamente  não será tão limpa e cheirosa quanto o psql).</p>
<p>Inicie uma transação em cada uma executando em ambas a instrução:</p>
<pre class="brush: sql;">

exercicio=# begin;
BEGIN
</pre>
<p>Na primeira, execute o seguinte comando:</p>
<pre class="brush: sql;">

exercicio=# UPDATE aluno set nome = 'Jose da Silva' where id = 2;
UPDATE 1

exercicio=# select * from aluno;
id |     nome
----+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
(5 rows)
</pre>
<p>Veja que o nome de Zezinho agora é Jose da Silva.</p>
<p>Realize a mesma consulta na segunda instância do psql:</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |   nome
----+-----------
1 | Huguinho
2 | Zezinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
(5 rows)
</pre>
<p>Como você atentou, os alunos continuam com seus nomes intactos. O que  a primeira transação modificou não foi sentido pela segunda. O motivo é  que se a primeira voltar atrás, a segunda já teria lido e tomado suas  próprias decisões baseando-se em dados inconsistentes. Confira como  faríamos para reverter (execute na primeira transação):</p>
<pre class="brush: sql;">

exercicio=# ROLLBACK ;
ROLLBACK
exercicio=# select * from aluno;
id |   nome
----+-----------
1 | Huguinho
2 | Zezinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
(5 rows)
</pre>
<p>Nossa base voltou ao estágio em que estava no momento do BEGIN.</p>
<h3>Unrepeatable Reads</h3>
<p>Leituras não repetíveis acontecem quando uma transação lê algum dado  em determinado momento, posteriormente outra transação altera ou deleta e  executa o COMMIT. A primeira volta a ler os mesmos dados e constata que  eles não estão mais como antes. Este não chega a ser um problema em  muitos sistemas, a ponto do PostgreSQL, em seu nível de isolamento  padrão, permitir que ocorra. Vejamos:</p>
<p>PSQL1: Iniciamos uma nova transação (aquela anterior foi desfeita com  ROLLBACK) e atualizamos novamente o nome de Zezinho.</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# UPDATE aluno set nome = 'Jose da Silva' where id = 2;
UPDATE 1
</pre>
<p>PSQL2: Como visto antes, nada foi percebido pela outra transação.</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |   nome
---+-----------
1 | Huguinho
2 | Zezinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
(5 rows)
</pre>
<p>PSQL1: Confirmamos a alteração</p>
<pre class="brush: sql;">

exercicio=# COMMIT ;
COMMIT
</pre>
<p>PSQL2: Agora a alteração foi sentida</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |     nome
---+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
(5 rows)
</pre>
<h3>Phantom Read</h3>
<p>O problema das leituras fantasmas é parecido com o das leituras não  repetíveis, o que muda é que uma das transações em vez de alterar o  conjunto de dados, insere um dado novo.</p>
<p>Vamos refazer a dinâmica. Primeiramente, encerre as transações das  duas instâncias do psql. Neste momento, tanto faz encerrar com COMMIT ou  com ROLLBACK. Se a transação não estiver em curso, você receberá uma  mensagem como esta:</p>
<pre>WARNING:  there is no transaction in progress</pre>
<p>PSQL1: Inicie a transação e insira duas novas alunas</p>
<pre class="brush: sql;">

# begin;
BEGIN
exercicio=# INSERT INTO aluno (nome) values ('Chiquinha'), ('Mariazinha');
INSERT 0 2
</pre>
<p>PSQL2: Inicie a transação e consulte a lista de alunos</p>
<pre class="brush: sql;">

# begin;
BEGIN
exercicio=# select * from aluno;
id |     nome
---+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
(5 rows)
</pre>
<p>Ninguém novo até agora.</p>
<p>PSQL1: Confirme sua transação com um COMMIT</p>
<pre class="brush: sql;">

exercicio=# COMMIT ;
COMMIT
</pre>
<p>PSQL2: Veja que as novas alunas agora estão presentes</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
id |     nome
---+---------------
1 | Huguinho
3 | Luisinho
4 | Juquinha
5 | Joaozinho
2 | Jose da Silva
6 | Chiquinha
7 | Mariazinha
(7 rows)
</pre>
<h2>Níveis de isolamento</h2>
<p>Existem quatro níveis de isolamento segundo o padrão SQL:</p>
<h3>READ UNCOMMITED</h3>
<p>Nível menos isolado. Aqui, todos os problemas citados podem ocorrer,  inclusive as porcas dirty reads. É muito difícil um SGBD permitir que o  DBA mesmo que deliberadamente configure o nível de isolamento para READ  UNCOMMITED. Em resumo, é um nível acadêmico, apenas para você dizer que  conhece.</p>
<h3>READ COMMITED</h3>
<p>Nível padrão do PostgreSQL. Aqui dirty reads estão barradas, mas,  como verificamos nos exercícios anteriores, unrepeatable reads e phantom  reads podem ocorrer.</p>
<h3>REPEATABLE READ</h3>
<p>Neste nível, apenas as phantom reads podem ocorrer. Os SGBDs fazem  bloqueio (lock) do conjunto de dados lidos em uma transação, o que evita  que as leituras posteriores apresentem resultados modificados ou  deletados confirmados por outra transação. No entanto, não há como fazer  lock de um registro que ainda não existia na primeira leitura. Este é o  motivo pelo qual as leituras fantasmas podem assombrar por aqui.</p>
<h3>SERIALIZABLE</h3>
<p>Esse é o nível que leva o isolamento ao máximo. Aqui, nenhum desses  problemas podem ocorrer.</p>
<h3>Em resumo:</h3>
<p>A tabela abaixo mostra os níveis de isolamento em relação aos  problemas que podem ou não provocar.</p>
<table class="CALSTABLE" border="1">
<col></col>
<col></col>
<col></col>
<col></col>
<thead>
<tr>
<th>Nível de isolamento</th>
<th>Dirty Read</th>
<th>Nonrepeatable Read</th>
<th>Phantom Read</th>
</tr>
</thead>
<tbody>
<tr>
<td>Read uncommitted</td>
<td>Possível</td>
<td>Possível</td>
<td>Possível</td>
</tr>
<tr>
<td>Read committed</td>
<td>Impossível</td>
<td>Possível</td>
<td>Possível</td>
</tr>
<tr>
<td>Repeatable read</td>
<td>Impossível</td>
<td>Impossível</td>
<td>Possível</td>
</tr>
<tr>
<td>Serializable</td>
<td>Impossível</td>
<td>Impossível</td>
<td>Impossível</td>
</tr>
</tbody>
</table>
<p>Para modificar o nível de isolamento da transação corrente, existe o  comando SET TRANSACTION que deve ser executado logo após o BEGIN e antes  de qualquer consulta SELECT, INSERT, DELETE, UPDATE, FETCH ou COPY.  Este comando possui o seguinte formato:</p>
<p>SET TRANSACTION [ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ |  READ COMMITTED | READ UNCOMMITTED } ]  [ {READ WRITE | READ ONLY} ]</p>
<p>Com ele, é possível determinar o nível de isolamento, escrevendo  ISOLATION LEVEL seguido por algum dos níveis já apresentados e/ou  informar as opções READ WRITE (padrão) ou READ ONLY. Transações READ  ONLY (somente leitura) não podem alterar nenhuma tabela que não seja  temporária.</p>
<p>Vamos a um exemplo:</p>
<pre class="brush: sql;">

exercicio=# begin;
BEGIN
exercicio=# set transaction read only;
SET
exercicio=# UPDATE aluno SET nome = 'teste';
ERROR:  cannot execute UPDATE in a read-only transaction
exercicio=# select * from aluno;
ERROR:  current transaction is aborted, commands ignored until end of transaction block
exercicio=# rollback;
ROLLBACK
</pre>
<p>Após o BEGIN, determinamos que nossa transação seria somente leitura.  Logo após, tentamos infringir o determinado em SET TRANSACTION  executando um UPDATE qualquer. Confira o erro resultante. Segui adiante  para mostrar algo que ainda não havia falado, mas ocorre sempre que uma  instrução retorna erro dentro de uma transação. Qualquer nova instrução  retorna o erro informando que a transação foi abortada. Cabe-nos apenas  executar o ROLLBACK para encerrar a transação problemática.</p>
<p>O nível de isolamento REPEATABLE READ no PostgreSQL é encarado como  um  SERIALIZABLE, ou seja, não permite leituras fantasmas. Vejamos:</p>
<p>PSQL1: Determinando o nível de isolamento para REPEATABLE READ, que  no PostgreSQL funciona como um SERIALIZABLE</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# SET transaction ISOLATION LEVEL REPEATABLE READ ;
SET
exercicio=# select * from aluno;
 id |     nome
---+---------------
 1 | Huguinho
 3 | Luisinho
 4 | Juquinha
 5 | Joaozinho
 2 | Jose da Silva
 6 | Chiquinha
 7 | Mariazinha
(7 rows)
</pre>
<p>PSQL2: Inserindo um novo aluno e confirmando a transação</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# INSERT INTO aluno (nome) values ('Maradona');
INSERT 0 1
exercicio=# COMMIT ;
</pre>
<p>PSQL1: Olha aí que Maradona ainda não foi inserido e não é porque ele  é argentino. Após a confirmação deste transação, ele vai aparecer. Só  espero que não estrague a festa.</p>
<pre class="brush: sql;">

exercicio=# select * from aluno;
 id |     nome
---+---------------
 1 | Huguinho
 3 | Luisinho
 4 | Juquinha
 5 | Joaozinho
 2 | Jose da Silva
 6 | Chiquinha
 7 | Mariazinha
(7 rows)

exercicio=# COMMIT ;
COMMIT
exercicio=# select * from aluno;
 id |     nome
---+---------------
 1 | Huguinho
 3 | Luisinho
 4 | Juquinha
 5 | Joaozinho
 2 | Jose da Silva
 6 | Chiquinha
 7 | Mariazinha
 8 | Maradona
(8 rows)
</pre>
<p>O  nível de isolamento READ UNCOMMITED é encarado como um READ COMMITED (o  padão). Assim, leituras sujas jamais são permitidas, no PostgreSQL.</p>
<h2>Bloqueios e controle de versão</h2>
<p>Ao contrário de alguns bancos de dados, o PostgreSQL por padrão  trabalha com controle de versão ao invés de bloqueio de dados na  manipulação de transações. Este mecanismo, conhecido como MVCC  (multi-version concurrency control) costuma ser bem mais eficiente em  termos de desempenho em comparação aos bloqueios de registros que já são  bem melhores do que os bloqueios de tabelas. Além do PostgreSQL, bancos  como Oracle, Firebird, HiperSonic, SyBase, ZODB, entre outros também se  baseiam no MVCC para controle de isolamento de transações.</p>
<p>Para  cada registro de cada tabela sempre existem dois campos utilizados  no  controle de transações. O campo xmin informa o id (auto-sequenciado)  da  transação que gerou este registro. Já xmax determina o id da  transação  que a deletou ou alterou seu conteúdo, gerando um novo  registro com  xmin atualizado. Para ilustrar como funciona o controle, vejamos o  exemplo:</p>
<p>PSQL1:</p>
<pre class="brush: sql;">

exercicio=# BEGIN ;
BEGIN
exercicio=# select *, xmin, xmax from aluno;
 id |     nome      | xmin | xmax
---+---------------+------+------
 1 | Huguinho      |  664 |    0
 3 | Luisinho      |  664 |    0
 4 | Juquinha      |  664 |    0
 5 | Joaozinho     |  664 |    0
 2 | Jose da Silva |  668 |    0
 6 | Chiquinha     |  669 |    0
 7 | Mariazinha    |  669 |    0
 8 | Maradona      |  670 |    0
(8 rows)

exercicio=# DELETE FROM aluno WHERE nome = 'Maradona';
DELETE 1
exercicio=# select *, xmin, xmax from aluno;
 id |     nome      | xmin | xmax
---+---------------+------+------
 1 | Huguinho      |  664 |    0
 3 | Luisinho      |  664 |    0
 4 | Juquinha      |  664 |    0
 5 | Joaozinho     |  664 |    0
 2 | Jose da Silva |  668 |    0
 6 | Chiquinha     |  669 |    0
 7 | Mariazinha    |  669 |    0
(7 rows)
exercicio=# UPDATE aluno SET nome = 'Zezinho' where id = 2;
UPDATE 1
exercicio=# select *, xmin, xmax from aluno;
 id |    nome    | xmin | xmax
---+------------+------+------
 1 | Huguinho   |  664 |    0
 3 | Luisinho   |  664 |    0
 4 | Juquinha   |  664 |    0
 5 | Joaozinho  |  664 |    0
 6 | Chiquinha  |  669 |    0
 7 | Mariazinha |  669 |    0
 2 | Zezinho    |  671 |    0
(7 rows)
</pre>
<p>No  primeiro SELECT, podemos visualizar o xmin de cada registro. Perceba  que Jose da Silva possui um xmin maior do que os outros alunos que foram  inseridos no mesmo momento. Isto se deve aos UPDATEs que executamos nos  exemplos posteriores ao primeiro INSERT.</p>
<p>Realizamos um DELETE  para excluir Maradona de onde ele não foi chamado. O SELECT posterior  não tem como vê-lo uma vez que o xmax é justamente o id da transação  atual. Após um UPDATE para voltarmos com o nome Zezinho do aluno 2, e  eis que surgiu um registro no fim da fila com id de transação maior do  que todos. O registro com Jose da Silva também não está mais visível  aqui.</p>
<p>Agora vamos a uma outra transação antes de confirmação as  alterações na atual.</p>
<p>PSQL2: Selecionando os registros em outra  transação antes do COMMIT da anterior</p>
<pre class="brush: sql;">

exercicio=#
SELECT *, xmin, xmax FROM aluno;
 id |     nome      | xmin | xmax
---+---------------+------+------
 1 | Huguinho      |  664 |    0
 3 | Luisinho      |  664 |    0
 4 | Juquinha      |  664 |    0
 5 | Joaozinho     |  664 |    0
 2 | Jose da Silva |  668 |  671
 6 | Chiquinha     |  669 |    0
 7 | Mariazinha    |  669 |    0
 8 | Maradona      |  670 |  671
(8 rows)
</pre>
<p>Nela, é possível visualizar os xmax de  Jose da Silva e Maradona com o valor da transação em PSQL1. Como a  primeira ainda não confirmou a transação, ainda não estamos vendo os  novos valores aqui (só veríamos se o nível de isolamento fosse READ  UNCOMMITED, que permite dirty reads e não é suportado pelo PostgreSQL).</p>
<p>Vamos  confirmar e visualizar o resultado final:</p>
<p>PSQL1: Confirmação e  visualização do resultado</p>
<pre class="brush: sql;">

exercicio=# COMMIT ;
COMMIT
exercicio=# select *, xmin, xmax from aluno;
 id |    nome    | xmin | xmax
---+------------+------+------
 1 | Huguinho   |  664 |    0
 3 | Luisinho   |  664 |    0
 4 | Juquinha   |  664 |    0
 5 | Joaozinho  |  664 |    0
 6 | Chiquinha  |  669 |    0
 7 | Mariazinha |  669 |    0
 2 | Zezinho    |  671 |    0
(7 rows)
</pre>
<p>PSQL2: Visualização atualizada. Se estivesse  no nível de isolamento SERIALIZABLE ou REPEATABLE READ, não seria  possível ver os registros atualizados e deletados (leituras não  repetíveis).</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/06/27/transacoes-no-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.especializa.com.br/blog/wp-content/uploads/2010/06/transacoes.mp4" length="4726382" type="video/mp4" />
		</item>
		<item>
		<title>Estamos de Luto</title>
		<link>http://especializa.com.br/blog/2010/06/22/estamos-de-luto/</link>
		<comments>http://especializa.com.br/blog/2010/06/22/estamos-de-luto/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 15:08:00 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[especializa]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=152</guid>
		<description><![CDATA[Inicio este post pedindo desculpas a quem espera encontrar aqui sempre informações técnicas. Desde que comecei a escrever o Blog da Especializa, sempre imaginei que só iria abrir parênteses para falar sobre conquistas de nossos professores, alunos e amigos como nos casos de Renato e de Glauber, mas por nos considerar uma família (perdão se [...]]]></description>
			<content:encoded><![CDATA[<p>Inicio este post pedindo desculpas a quem espera encontrar aqui sempre informações técnicas. Desde que comecei a escrever o Blog da Especializa, sempre imaginei que só iria abrir parênteses para falar sobre conquistas de nossos professores, alunos e amigos como nos casos de <a href="http://especializa.com.br/blog/2010/06/08/nero-vai-a-nasa/" target="_blank">Renato</a> e de <a href="http://especializa.com.br/blog/2010/06/17/professor-da-especializa-emplaca-mais-uma-capa-da-webmobile/" target="_blank">Glauber</a>, mas por nos considerar uma família (perdão se fui muito piegas), acredito que devemos estar juntos também em momentos de tristeza.</p>
<p>Na semana passada, tivemos um susto enorme após a notícia do problema de saúde de nosso professor Aercio Ramoa. Ele sofreu um infarto e passou alguns dias na UTI, mas felizmente, se recupera bem, já está na enfermaria e até já demonstrou sua peculiar preocupação com seus alunos querendo saber o que vimos na aula em que eu o substitui. Acreditamos que após a pausa do feriado de São João, já estaremos com Aercio firme e forte. Boa sorte, amigo.</p>
<p>No entanto, este post não será tão alegre até o final. Infelizmente, o filho de nosso grande amigo Habner Carlos faleceu. Habner foi nosso aluno de PHP. Determinado, enfrentou e venceu a prova de certificação da Zend mesmo antes de concluir as aulas. Profissional e interessado, também nos provou que teria plenas condições de ser professor e em cada turma que ministrou, só ouvi elogios à sua competência, didática e amizade com os alunos. Quem o acompanhou nesses últimos meses, sabe o quanto ele estava vibrando com a primeira gravidez de sua esposa. Como se espera de um homem de Deus e de um perfeito futuro pai, fez planos e não via a hora de poder abraçar seu filho.</p>
<p>Após o parto, seu filho teve algumas complicações e ficou internado batalhando pela vida até que não resistiu e descansou.</p>
<p>O sentimento de pesar é extremamente desconfortante para que eu consiga  encontrar as palavras certas que lhe dêem apoio nesta hora, mas Hábner, gostaria de dizer a você, à sua esposa, parentes e amigos que tenham muita força. Vocês não estão sozinhos. Todos nós da Especializa partilhamos deste sentimento de dor e principalmente de esperança na superação de vocês.</p>
<p>Saiba, meu amigo, que seu filho não se foi. Prefira encarar que Deus sentiu saudades e o chamou de volta, mas não será para sempre. Muito em breve, Ele o plantará novamente no ventre de sua esposa e vocês três poderão curtir uma vida longa e alegre juntos. A vantagem é que serão muito mais fortes e unidos que qualquer outra família.</p>
<p>Um grande abraço.</p>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/06/22/estamos-de-luto/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>PostgreSQL 9.0 quase no ponto</title>
		<link>http://especializa.com.br/blog/2010/06/18/postgresql-9-0-quase-no-ponto/</link>
		<comments>http://especializa.com.br/blog/2010/06/18/postgresql-9-0-quase-no-ponto/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 04:41:37 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[especializa]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=133</guid>
		<description><![CDATA[No último dia 6, o PostgreSQL Global Development Group anunciou o provável último beta da versão 9.0 do servidor de banco de dados open source mais avançado do mundo. A previsão oficial é até o mês de setembro deste ano, mas alguns acreditam que a versão final saia do forno ainda neste mês.
Como não poderia [...]]]></description>
			<content:encoded><![CDATA[<p>No último dia 6, o PostgreSQL Global Development Group anunciou o provável último beta da versão 9.0 do servidor de banco de dados open source mais avançado do mundo. A previsão oficial é até o mês de setembro deste ano, mas alguns acreditam que a versão final saia do forno ainda neste mês.</p>
<p>Como não poderia deixar de ser, nós da Especializa acompanhamos sem piscar os olhos e já estamos preparando <a href="http://www.especializa.com.br/postgresql" target="_blank">nossos cursos</a> para tão logo possamos considerar as novidades definitivas.</p>
<p>Vejamos o que virá de tão bom a ponto da versão haver mudado de número (inicialmente, seria 8.5).</p>
<p><span id="more-133"></span>A versão 8 do PostgreSQL foi um marco histórico bastante importante para este SGBD. Talvez a principal razão tenha sido o tão esperado suporte nativo a sistemas de arquivos NTFS e, consequentemente, a capacidade de rodar em ambientes Windows.</p>
<p>Apesar do mundo Unix dominar largamente os servidores que rodam o PostgreSQL, mesmo após a oitava versão, suportar nativamente o Windows, foi um passo importante na busca pela popularização de um banco sempre considerado robusto, mas pouco atraente em termos de facilidade de administração.</p>
<p>O raciocínio é óbvio. Mais gente utilizando traz naturalmente mais gente disposta a desenvolver ferramentas para melhorar o dia-a-dia de quem utiliza.</p>
<p>Após quatro rodadas de atualizações da versão 8, que apesar de <em>minor realeases</em> (incremento do número após o ponto, 8.1, 8.2, 8.3 e 8.4), evoluíram consideravelmente o PostgreSQL em diversas áreas, estava claro que lançar uma versão 9 certamente significaria uma responsabilidade muito grande. Mesmo assim, a comunidade open source achou que o que eles estavam trabalhando não poderia ser apenas um 8.5.</p>
<p>Acredito que estamos tratando de um SGBD maduro que provavelmente será difícil encontrar alguma <em>new feature</em> que por si só já o transporte a uma nova versão. O motivo para chamar o PostgreSQL de 9.0 agora foi a quantidade de melhorias implementadas pela comunidade. Só para se ter uma idéia, foram catalogados 84 desenvolvedores produzindo mais de 200 melhorias e correções nesta versão.</p>
<p>Um ponto positivo para o PostgreSQL é a descentralização de desenvolvedores, sendo possível notar que muitos dos principais colaboradores do núcleo do sistema trabalham numa gama bem variada de empresas. Isto de certa forma potencializa a garantia de que os planos não serão mudados de uma hora pra outra.</p>
<p>É, estou sim me referindo à celeuma envolvendo o MySQL quando a Oracle adquiriu a Sun e provocou dissidências como o <a href="http://www.mariadb.org" target="_blank">MariaDB</a> e algumas incertezas quanto ao seu futuro. Ingenuamente, podemos pensar &#8220;ah, o MySQL não é open source? Então se a Oracle quiser matá-lo a comunidade vem e cria um fork dele&#8221; (calma que não foi bem isso que ela anunciou que faria).</p>
<p>Tudo bem, existem diversos exemplos de forks na comunidade que alcançaram sucesso igual ou maior que seu progenitor (sem ir muito longe, o próprio Firebird nasceu da abertura do fonte do Interbase da Borland). Mas a realidade não é tão simples. Muitas vezes, optar por um concorrente próximo quando seu produto open source favorito parece um tanto &#8220;sem futuro&#8221; é a solução mais rápida e indolor. E aí, quando a comunidade amadurecer o fork recém nascido, já era! A própria comunidade talvez já tenha abandonado a criança.</p>
<p>Por outro lado, essa pulverização de empresas e profissionais contribuidores pode refletir em uma falta de personalidade própria, se é que posso chamar assim. Em outras palavras, um gestor de TI ao refletir sobre utilizar ou não o PostgreSQL em seus servidores pode se questionar: Quem está por trás dele? Quem garante que ele vai atender às minhas necessidades? E quem é a pessoa mais indicada para me informar qual a maneira ideal de adaptar o PostgreSQL à minha realidade? Neste momento, os &#8220;<em>quens</em>&#8221; certamente serão preenchidos por empresas que talvez ele nunca tenha ouvido falar.</p>
<p>Por isso, o fortalecimento de empresas como a EnterpriseDB (praticamente o Quem por trás hoje), a Command Prompt e a própria PostgreSQL Experts encabeçada por Josh Berkus pode ser saudável. Some a elas as presenças de gigantes como Sun (Oracle), Red Hat e Google, todas estas com <em>major contributors</em> focados no PostgreSQL, para garantir de que se a EnterpriseDB um dia for comprada pela Microsoft (só para dar um exemplo mais dramático) ela não terá como simplesmente matar o PostgreSQL.</p>
<p>O nosso ponto de partida no estudo das novidades é o Wiki oficial, mais especificamente no endereço:</p>
<p><a href="http://wiki.postgresql.org/wiki/Development_information" target="_blank">http://wiki.postgresql.org/wiki/Development_information</a>. Lá você encontrará diversas informações e links interessantes como a <a href="http://www.postgresql.org/about/featurematrix" target="_blank">Feature Matrix</a> apresentando o que vem sendo implentando desde a versão 7.4</p>
<p>Robert Treat, da OmniTI e <em>major contributor</em> do PostgreSQL, elenca em sua <a href="http://www.slideshare.net/xzilla/intro-to-postgres-9-tutorial" target="_blank">palestra</a> melhorias em performance, administração, desenvolvimento e procedimentos. Podemos destacar:</p>
<ul>
<li>
<h2>Ordered aggregates</h2>
</li>
</ul>
<p>Dados podem ser previamente ordenados antes de serem fornecido a alguma função de agregação. <a href="http://www.depesz.com/index.php/2010/01/06/waiting-for-8-5-ordered-aggregates/" target="_blank">Este link</a> trata do assunto usando array_agg().</p>
<ul>
<li>
<h2>Window functions</h2>
</li>
</ul>
<p>Na verdade elas já existiam desde o PostgreSQL 8.4 (você pode conferir na Feature Matrix), mas agora novas funcionalidades para elas foram criadas. <a href="http://www.postgresonline.com/journal/index.php?/archives/119-Running-totals-and-sums-using-PostgreSQL-8.4-Windowing-functions.html" target="_self">Este link</a> introduz o assunto, abordando as cláusulas PARTITION e WINDOW. Já <a href="http://www.postgresonline.com/journal/index.php?/archives/122-Window-Functions-Comparison-Between-PostgreSQL-8.4,-SQL-Server-2008,-Oracle,-IBM-DB2.html" target="_blank">este link</a> faz um comparativo do suporte a essa funcionalidade, parte do padrão ANSI SQL 2003, no PostgreSQL 8.4 com o SQL Server 2008, Oracle e DB2.</p>
<p><a href="http://www.depesz.com/index.php/2010/02/17/waiting-for-9-0-extended-frames-for-window-functions/" target="_blank">Aqui</a>, você pode encontrar algo sobre o que há de novo no 9.0 dentro deste assunto.</p>
<ul>
<li>
<h2>Join removal</h2>
</li>
</ul>
<p>O planejador de consultas do PostgreSQL pode excluir do plano tabelas que não são necessárias para obtenção dos dados resultantes. Leia mais, <a href="http://rhaas.blogspot.com/2010/06/why-join-removal-is-cool.html" target="_blank">aqui</a>.</p>
<ul>
<li>
<h2>Explain buffers</h2>
</li>
</ul>
<p>O comando explain agora exibe também as páginas de dados envolvidas em consultas. Buffers são unidades normalmente de 8kb que armazenam os dados de fato.</p>
<ul>
<li>
<h2>Grant em esquema</h2>
</li>
</ul>
<p>Comandos Grant e Revoke podem ser aplicados  a esquemas. <a href="http://www.depesz.com/index.php/2009/11/07/waiting-for-8-5-grant-all/" target="_blank">Confira</a>.</p>
<ul>
<li>
<h2>Suporte a Windows de 64 bits</h2>
</li>
</ul>
<ul>
<li>
<h2>Initdb chamado via pg_ctl</h2>
</li>
</ul>
<p>O executável postgres já era chamado via pg_ctl, agora o initdb também poderá ser.</p>
<ul>
<li>
<h2>Triggers condicionais</h2>
</li>
</ul>
<p>Triggers agora contam com a cláusula WHEN para avaliar uma expressão boleana e decidir se devem ou não ser disparada.</p>
<ul>
<li>
<h2>PL/pgSQL</h2>
</li>
</ul>
<p>A linguagem procedural mais utilizada no PostgreSQL já vem instalada nativamente. Claro que você poderia realizar um CREATE LANGUAGE plpgsql; em template1 que tava tudo resolvido.  Também houve melhorias na sintaxe da linguagem.</p>
<ul>
<li>
<h2>Hot Standby</h2>
</li>
</ul>
<p>O tão esperado recurso de replicação que viria no 8.4, agora veio.</p>
<ul>
<li>
<h2>Streaming replication</h2>
</li>
</ul>
<p>Mais um recurso interessante para replicações. Confira mais <a href="http://wiki.postgresql.org/wiki/Streaming_Replication" target="_blank">aqui</a>.</p>
<ul>
<li>
<h2>pg_upgrade</h2>
</li>
</ul>
<p>Ferramenta para facilitar o processo de upgrade de versão de um cluster PostgreSQL.</p>
<p>Há ainda diversas outras melhorias.</p>
<p>Fica a promessa aqui de escrever algum tutorial explicando algumas delas.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 1595px; width: 1px; height: 1px; overflow: hidden;">
<pre class="PROGRAMLISTING">CREATE LANGUAGE plpgsql;</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/06/18/postgresql-9-0-quase-no-ponto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Professor da Especializa emplaca mais uma capa da WebMobile</title>
		<link>http://especializa.com.br/blog/2010/06/17/professor-da-especializa-emplaca-mais-uma-capa-da-webmobile/</link>
		<comments>http://especializa.com.br/blog/2010/06/17/professor-da-especializa-emplaca-mais-uma-capa-da-webmobile/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 05:52:12 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[antena]]></category>
		<category><![CDATA[especializa]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javame]]></category>
		<category><![CDATA[webmobile]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=136</guid>
		<description><![CDATA[Assim nosso mestre Nelson Glauber vai acabar virando colunista fixo da conceituada revista WebMobile, da DevMedia. Após um artigo sobre automações de tarefas em Java ME com Ant + Antena na edição 29, agora a 30 também estampa um artigo seu na capa.
A edição deste mês destaca seu comparativo Android x iPhone, vale a pena [...]]]></description>
			<content:encoded><![CDATA[<p>Assim nosso mestre Nelson Glauber vai acabar virando colunista fixo da conceituada revista WebMobile, da DevMedia. Após <a href="http://nglauber.blogspot.com/2010/04/artigo-ant-antena-com-java-me.html" target="_blank">um artigo</a> sobre automações de tarefas em Java ME com Ant + Antena na edição 29, agora a 30 também estampa um artigo seu na capa.</p>
<p>A edição deste mês destaca seu comparativo <a href="http://nglauber.blogspot.com/2010/06/artigo-android-x-iphone.html" target="_blank">Android x iPhone</a>, vale a pena conferir.</p>
<p>Parabéns Glauber! Este é apenas o reconhecimento da mídia especializa de sua competência e dedicação.</p>
<p>Ah, será que vale deixar um spoiler da edição 31? Provavelmente, ele estará lá de novo e desta vez mau acompanhado. =)</p>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/06/17/professor-da-especializa-emplaca-mais-uma-capa-da-webmobile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nero vai à Nasa</title>
		<link>http://especializa.com.br/blog/2010/06/08/nero-vai-a-nasa/</link>
		<comments>http://especializa.com.br/blog/2010/06/08/nero-vai-a-nasa/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 14:30:23 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[especializa]]></category>
		<category><![CDATA[nasa]]></category>
		<category><![CDATA[nero]]></category>
		<category><![CDATA[tecnologia]]></category>
		<category><![CDATA[vocenofuturo.com]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=129</guid>
		<description><![CDATA[Carlos Renato &#8220;Nero&#8221; Azevedo, professor da Especializa, foi aprovado e vai para a Singularity University em Mountain View, California e você poderá acompanhar todos os seus passos.
Desculpem a propaganda forçada no parágrafo anterior. Ser professor da Especializa é um mero e imperceptível detalhe no currículo do cara. Renato é especialista em TI com alma de [...]]]></description>
			<content:encoded><![CDATA[<p>Carlos Renato &#8220;Nero&#8221; Azevedo, professor da Especializa, foi aprovado e vai para a Singularity University em Mountain View, California e você poderá acompanhar todos os seus passos.</p>
<p>Desculpem a propaganda forçada no parágrafo anterior. Ser professor da Especializa é um mero e imperceptível detalhe no currículo do cara. Renato é especialista em TI com alma de cientista. Maluco? Não importa. O fato é que (segundo seu próprio blog):</p>
<p>Em Março de 2010, Carlos recebeu a notícia de sua aprovação no <em>Graduate  Studies Program 2010</em> da <a rel="nofollow" href="http://singularityu.org/" target="_blank">Singularity University</a> (SU), um programa de estudos oferecido a estudantes de pós-graduação  com demonstrada capacidade de liderança e conhecimentos avançados em  suas respectivas áreas de pesquisa.</p>
<p>Nero, como vocês podem chamar, lançou o blog <a href="http://vocenofuturo.com/" target="_self">Você no Futuro</a>, onde deve discutir uma série de tecnologias emergentes como inteligência artificial, robótica, ciências espaciais, neurociência, bioengenharia, bioinformática, energia &amp; meio ambiente, nanotecnologia, invação &amp; empreendedorismos, ética, filosofia &#8230; ufa. Por lá você vai encontrar notícias, entrevistas, vídeos e podcasts, além de acompanhar toda a saga de Renato de Recife ao Campus da NASA.</p>
<p>Ele estará por lá de 19 de Junho a 28 de Agosto e deverá &#8220;topar&#8221; com um pessoal bem fraquinho como Bob Metcalfe (pai do Ethernet) e Vint Cerf (pai do TCP/IP), além de poder brincar no quintal da Google e do Facebook. Enfim, pra quem é nerd, cada post dele vai ser muito melhor do que qualquer episódio do The Big Bang Theory.</p>
<p>Se você é como a gente e se interessou em ajudar, vale dizer que Renato, a princípio, se sente constrangido em colocar algo do tipo &#8220;clique aqui para fazer uma doação&#8221;. Não que ele seja rico e já tenha como se bancar, muito pelo contrário, cientista e professor da Especializa infelizmente &#8220;ainda&#8221; não é o perfil de uma pessoa que possa passear na California. Mas Nero pretende recorrer a autoridades e diretores de empresas para que o ajudem no custeio, em troca de ceder um pequeno espaço para publicação de quem o está patrocinando.</p>
<p>O que nos cabe é prestigiar o blog do nosso nobre conterrâneo, espalhando até para os cachorros dos amigos dos tios dos vizinhos dos nossos primos. Mas, claro, se você quer ajudar com alguma quantia, basta enviar um email pra ele.</p>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/06/08/nero-vai-a-nasa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Multimidia na web &#8211; áudio, video, flash, html5 e quem mais tiver a ver com tudo isso</title>
		<link>http://especializa.com.br/blog/2010/06/06/multimidia-na-web-audio-video-flash-html5-e-quem-mais-tiver-a-ver-com-tudo-isso/</link>
		<comments>http://especializa.com.br/blog/2010/06/06/multimidia-na-web-audio-video-flash-html5-e-quem-mais-tiver-a-ver-com-tudo-isso/#comments</comments>
		<pubDate>Sun, 06 Jun 2010 02:13:37 +0000</pubDate>
		<dc:creator>especializa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[h264]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[ogg]]></category>
		<category><![CDATA[software livre]]></category>
		<category><![CDATA[theora]]></category>
		<category><![CDATA[vorbis]]></category>
		<category><![CDATA[vp8]]></category>
		<category><![CDATA[webm]]></category>

		<guid isPermaLink="false">http://especializa.com.br/blog/?p=116</guid>
		<description><![CDATA[Olá amigos,
Há tempos que venho interessado em comentar algo sobre o suporte a multimidia na Web. Sou do tempo em que a Web não era lugar para sons, muito menos video. A gente tinha que se aventurar em plugins ou componentes ActiveX para obter .mid no Netscape ou até mesmo MP3 no Internet Explorer, respectivamente. [...]]]></description>
			<content:encoded><![CDATA[<p>Olá amigos,</p>
<p>Há tempos que venho interessado em comentar algo sobre o suporte a multimidia na Web. Sou do tempo em que a Web não era lugar para sons, muito menos video. A gente tinha que se aventurar em plugins ou componentes ActiveX para obter .mid no Netscape ou até mesmo MP3 no Internet Explorer, respectivamente. Mas o troço era tão ruim que as pessoas até se assustavam se um site resolvesse tocar aquelas  &#8220;musiquinhas&#8221; que já foram febre nos celulares paleozóicos.</p>
<p>Vamos discutir aqui sobre a evolução dessas coisas, mas não tenho interesse em apresentar verdades absolutas. Se você tiver interesse em discutir a respeito e tiver uma idéia mais esclarecida do que a minha, eu lhe peço por favor, clique em &#8220;leia o resto deste post&#8221; e me ajude com as próximas linhas.</p>
<p><span id="more-116"></span>Lá vamos nós &#8230;</p>
<p>Eis que veio o Flash. Tá, quem me conhece sabe que nunca fui o maior defensor da tecnologia, mas justiça seja feita, a Web evoluiu com ele.</p>
<p>Por que nunca fui fã? Vamos lá: No início, os sites apresentavam aquelas infames apresentações iniciais. A sorte era quando havia um &#8220;pular introdução&#8221;. Nada mais amador do que aquelas apresentações. Depois alguns webdesigners se aventuraram em fazer sites completamente em Flash. O visual era bacana, mas a acessibilidade era dantesca. Imorais aquelas barras de rolagem estilizadas que sempre davam lag no browser e não funcionavam ao scroll do mouse. A Macromedia, que havia comprado a Future Splash (criadora do Flash) e aposentado seu produto concorrente Shockwave Director, foi comprada pela Adobe, esta sim, uma referência de qualidade em seus produtos: Postscript, Acrobat e talvez o mais famoso deles, Photoshop, são só alguns exemplos de fantásticas tecnlogias da Adobe. As coisas melhoraram bastante, mas infelizmente, a esta época eu, que já era fã incondicional do software livre e usuário, digamos, full-time, do Linux, continuei a sofrer com o famigerado Flash-plugin-non-free. Isso para não falar que meu amigo e professor da Especializa, Rafael Manzella, engenheiro de posicionamento há anos, realizador de campanhas de <a href="http://www.especializa.com.br/seo" target="_blank">SEO</a> para várias grandes empresas enquanto morava na Espanha, sempre me disse é FREUD fazer posicionamento de sites em Flash.</p>
<p>Por que acho que evoluiu? Porque estes mesmos designers descobriram que era possível usar o flash para interfaces ricas e foi difícil tornar o termo RIA (Rich Internet Application), sugerido pela Macromedia, mais amplo e abranger outras técnicas como o Ajax/Comet, Silverlight ou JavaFX. Outra razão foi o suporte a streaming de audio e video. As notícias ficaram mais vivas e avançamos à era do <a href="http://www.youtube.com" target="_blank">broadcast yourself</a>.</p>
<p>No auge das discussões sobre o HTML5, o padrão para adoção dessas midias parece que ainda vai dar o que falar. Para isso, mais uma vez vou precisar enrolar beeeem muito: No período das grandes navegações na Web, <em>Cristóvão Colombo descobriu o MP3</em>. O problema é que o MP3, ou MPEG-1 Audio Layer 3 (MPEG = Moving Picture Experts Group) é propriedade de um instituto de pesquisa alemão e da empresa Thomson Consumer Electronics e, desde 1998, quem fabrica player MP3 <span style="text-decoration: underline;">comercial</span> precisa pagar royalties pros caras.</p>
<p>A comunidade de software livre resolveu criar um padrão de mídia como patrimônio da humanidade. A este padrão deram o nome de Ogg, mantido pela fundação <a href="http://www.xiph.org/ogg/" target="_blank">Xiph.org</a>. Só que o Ogg é um guarda-chuva de padrões multimídia. O codec de audio foi denominado Ogg Vorbis. Este sim, o candidato da comunidade open source a substituto do MP3.</p>
<p>Com relação a video o desafio foi ainda maior. A empresa On2 Technologies, liberou o código de seu codec VP3 e a comunidade lançou seu produto Ogg Theora, comparável ao padrão MPEG-4.</p>
<p>Paralelo a isso, a Apple vem trabalhando em um codec de vídeo derivado de seu Quicktime, para uns conhecido como MPEG-4 parte 10 ou MPEG-4 AVC, mas que vem sendo chamado no mercado pelo seu código mesmo H.264 (exato, veio depois do H.263). Sites como o Youtube e o ITunes disponibilizam vídeos em H.264 e dispositivos como tocadores blu-ray, IPhones, ITabs, Androids, Blackberries e Maemos possuem suporte a decodificação diretamente no chip, sem uso de software, o que economiza energia. Saiba que este foi um dos motivos técnicos que fizeram Steve Jobs condenar o uso do Flash.</p>
<p>A Google adquiriu a On2 Technologies e entregou mais uma versão de seu codec à comunidade. O VP8 vem despontando como um concorrente de peso ao cargo de codec padrão de vídeos HTML5. Aliando-o ao codec de audio Ogg Vorbis, nosso MP3 realmente livre, empresas como a fundação Mozilla, a Opera Software, A Google e &#8230; a Adobe criaram o projeto <a href="http://www.webmproject.org/" target="_blank">WebM</a> com o objetivo de unir forças em prol da ubiquidade destes padrões.</p>
<p>Se tio Steve <a href="http://www.apple.com/hotnews/thoughts-on-flash/" target="_blank">levanta motivos para não usar o Flash</a> e se une à Google e à comunidade de software livre para preencher com HTML5 as lacunas dos padrões abertos das interfaces ricas na Web, é pau pra comer sabão. Se a Adobe se une também ao Google e à comunidade de software livre para promover o VP8, suportando este codec nos flash players, em detrimento do H.264 da Apple, é pau pra saber que sabão não se come.</p>
<p>Nessa história toda, a Google posa de boa moça, parceira dos padrões abertos e paladina na luta contra o <em>draconian future</em>, mas é a comunidade de software livre que sai vencedora. Seus padrões estão enfim conquistando o mundo e é o mundo quem se beneficia com isso.</p>
]]></content:encoded>
			<wfw:commentRss>http://especializa.com.br/blog/2010/06/06/multimidia-na-web-audio-video-flash-html5-e-quem-mais-tiver-a-ver-com-tudo-isso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

