quarta-feira, 29 de abril de 2009

Testes de unidade, Azure e confiabilidade

Eu sou um grande fã dos testes de unidade, e mesmo não sendo um profundo estudioso do assunto testes, minha vida como desenvolvedor passou por uma transformação depois que eu comecei a trabalhar com eles, hoje eu não vivo sem.

Para ilustrar como os testes me ajudam, vou descrever um pouco do que eu fiz recentemente e, quem sabe, você também vai se sentir compelido a adotar essa boa prática de programação.

Primeiro eu codifiquei um wrapper para uma classe do projeto StorageClient que vem junto com o SDK do Azure e depois, para garantir que tudo irá funcionar corretamente, eu escrevi um teste que tentava criar uma série de containers passando com parâmetros os nomes mais esdrúxulos, conforme vocês podem ver abaixo:

Assert.IsTrue(ger.CriaContainer(@"ML:K()*_%^%$#@!@$#%^GBDF HGDSFKhf hdf kjh"));
Assert.IsTrue(ger.CriaContainer(@"~!#anjnd_)(* 8923849790>""?><>MarshalByRefObjectAssert.IsTrue(ger.CriaContainer(@"|{})_(*()*&h12h8934njkhf1"));
Assert.IsTrue(ger.CriaContainer(@"~!#anjnd_)(* 8923849790>"<>MarshalByRefObjectAssert.IsTrue(ger.CriaContainer(@"[]@#$|\\\skj382oflkuy"));
Assert.IsTrue(ger.CriaContainer(@"~s 092k3 jk3098 \\[hshsh"));

O método CriaContainer tenta limpar os nomes informados, deixando somente caracteres válidos. Porém eu somente comecei a escrever o método de limpeza do nome depois que meu teste estava pronto. O que eu fazia então...

while (ExecutaTeste() != tudoOk){
Luti_EscreveDireitoFuncaoLimpeza();
}

Enquanto o meu teste não passava todinho (o local storage do Azure gerava uma Exceção), eu continuava melhorando o método de limpeza. Depois de algumas iterações desse loop, o teste mostrou aquele check verdinho, tudo 100%.

Feito esse e mais outros testes, todos executando com sucesso, resolvi testar meu código diretamente contra a nuvem. Alterei o App.Config do meu projeto de testes para usar minha conta do Azure e executei a bateria com 10 testes: Verde, Verde, Verde, Verde, VERMELHO!

Uai, estava tudo certo?! Olha daqui, olha dali, vejo o problema. O armazenamento local permite que eu crie um container com o nome parecido com "empresa---xxx". O problema é que se olharmos a documentação, veremos "Every dash (-) character must be immediately preceded and followed by a letter or number".Ugh.

Resultado: o ambiente de desenvolvimento local não checa essa regra.
Sabe quando eu acho que iria encontrar um erro desse tipo se não fossem pelos testes, provavelmente em produção!!!

Depois disso alterei meu código para refletir os requisitos do Azure, re-executei os testes de unidade e tudo verde. Lindo.

Mas a coisa não termina por aí não. Depois de concluído os testes, resolvi baixar e instalar o CTP de Março (ainda estava com o de Janeiro). Instalei tudinho e adivinha qual foi a primeira coisa que eu fiz? Executei novamente minha bateria de testes... Tudo certo, então até que me provem o contrário, a instalação foi um sucesso.

Qual o meu sentimento no fim das contas? Eu estou confiando bastante no meu código e, toda vez que houver alguma alteração eu não vou precisar ficar 45 minutos para testar se houve alguma mudança que me prejudica, basta eu executar meus testes novamente que em alguns segundos eu saberei a resposta.

Gostou?

[]s
Luciano Caixeta Moreira
luciano.moreira@srnimbus.com.br
luticm79@hotmail.com

quinta-feira, 23 de abril de 2009

Webcast na próxima semana - MSDN Brasil

Aproveitando que já estou por aqui, na próxima semana eu farei o meu primeiro webcast para o MSDN Brasil fora da Microsoft, onde irei abordar um tópico muito importante: segurança! Então na próxima quarta-feira pegue seu almoço mais cedo e vamos conhecer um pouco mais do SQL Server e seus mecanismos de segurança. Segue a descrição completa do evento...

Url do evento: https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032414719&EventCategory=4&culture=pt-BR&CountryCode=BR
Produto(s): Microsoft SQL Server 2008 e Segurança
Público(s): Desenvolvedores e administradores de banco de dados.
Apresentador(es): Luciano Moreira, Weber Ress
Duração: 60 Minutos
Data de Início: quarta-feira, 29 de abril de 2009 12:00 Brasília
Visão Geral do Evento

Garantir a segurança dos dados armazenados no seu banco de dados é uma tarefa que envolve vários aspectos que devem ser analisados com cuidado. Essa sessão irá explorar mecanismos de segurança do SQL Server 2008 para autenticação, autorização e criptografia, descrevendo como elas podem ser combinadas e integradas com sua aplicação, diminuindo a chance de um atacante conseguir acesso indevido aos seus dados.

[]s
Luciano Caixeta Moreira
luciano.moreira@srnimbus.com.br
luticm79@hotmail.com

Portal do grupo SQLServerDF

Conforme mencionei ontem, estou trabalhando na formalização do grupo SQLServerDF. O site está no ar e agora estou o configurando para ficar minimamente apresentável. O endereço é: http://sqlserverdf.sqlpass.org/.

Faça o seu cadastro e receba as newsletters do grupo. Aí eu aproveito e vejo direitinho como é feita a gerência dos usuários. hahahaha
Feedbacks sempre bem vindos.

[]s
Luciano Caixeta Moreira
luciano.moreira@srnimbus.com.br
luticm79@hotmail.com

quarta-feira, 22 de abril de 2009

Novo PASS chapter do Brasil - SQLServerDF


Bom dia pessoal.
Ultimamente eu ando fazendo bastante trabalho nos bastidores para trazer boas novidades para todos nós. Uma das novidades gostosas de anunciar é a criação do novo PASS chapter do Brasil, o SQLServerDF.

Para quem não sabe, o PASS (www.sqlpass.org) que dizer Professional Association for SQL Server e é uma organização independente, sem fins lucrativos, voltadas para a troca de conhecimento e experiência em assuntos relacionados ao SQL Server, ajudando a comunidade de profissionais interessada no tema.

A bandeira e o apoio do PASS será muito importante para continuação de um trabalho que eu já vinha desenvolvendo aqui em Brasília (pela Microsoft), que eram os encontros técnicos de SQL Server. Agora teremos um escopo mais amplo e uma organização diferenciada, onde tenho certeza, contarei com a ajuda de muitos entusiastas do Distrito Federal e, tomara, Brasil.

Então, é com muita alegria que transcrevo aqui a frase mais importante da última semana: "We would like to welcome SQLServerDF as our newest Chapter". :-)

Estou trabalhando agora para criar o nosso portal e marcar a reunião de abertura do grupo, que acontecerá em Maio.

Deixo aqui a missão do PASS: "Empower the global Microsoft SQL Server community to collaborate, learn, grow and be inspired through knowledge sharing and peer-based learning".

[]s
Luciano Caixeta Moreira
luciano.moreira@srnimbus.com.br
luticm79@hotmail.com

quinta-feira, 16 de abril de 2009

Novo whitepaper - Troubleshooting Performance Problems with SQL Server 2008

Acredito que muitos de vocês acompanham outros blogs de SQL Server e podem ter visto essa notícia, mas essa não tenho como deixar passar.

Saiu a versão atualizada de um whitepaper muito bom: Troubleshooting Performance Problems with SQL Server 2008. (http://download.microsoft.com/download/D/B/D/DBDE7972-1EB9-470A-BA18-58849DB3EB3B/TShootPerfProbs2008.docx).
Leitura obrigatória para todos que trabalham com o SQL Server 2008.

Eu estou assistindo a um vídeo muito bom sobre xEvents. Depois vou brincar um pouco e colocarei para vocês mais sobre o assunto.

[]s
Luciano Caixeta Moreira
luciano.moreira@srnimbus.com.br
luticm79@hotmail.com

segunda-feira, 13 de abril de 2009

Treinamento de SQL Server 2008/2005 - Arquitetura, funcionamento e desempenho

Bom dia pessoal.
Eu tenho trabalhado nos últimos dias em um treinamento diferenciado de SQL Server 2008/2005, voltado para profissionais que já trabalham com o SQL Server e querem aprofundar os seus conhecimentos com o produto.
A idéia do treinamento é discutirmos em 36 horas a arquitetura e estruturas internas do SQL Server, passando posteriormente para uma análise de desempenho e considerações de performance.

Minha proposta para esse treinamento é trabalhar com uma turma reduzida, mas experiente, usando as 36 horas para passar uma grande quantidade de informações. Por isso o curso não conta com laboratórios, o que me permitirá passar de 30% a 40% mais informações do que um treinamento tradicional. Escolha consciente, pois não vejo muito fundamento em termos laboratórios para analisar estruturas internas ou simular problemas, que raramente possuem a complexidade de questões encontradas no cotidiano.

De qualquer maneira, quem já viu alguma apresentação minha, sabe que sou uma pessoa que adora demos e análises detalhadas, então podemos esperar um treinamento avançado e bem divertido!

Você pode fazer o download do arquivo com a ementa pública do treinamento (http://cid-e145f7753042d628.skydrive.live.com/self.aspx/Public/SrNimbus/SQL06%20%7C5Beta%7C6%20[Ementa%20p%c3%bablica]%20-%20Arquitetura,%20funcionamento%20e%20desempenho.pdf), para entender melhor a proposta. Caso tenha interesse em fazer o treinamento, podemos ver a possibilidade de levá-lo para sua cidade e, no caso de São Paulo, já estamos com preço e sugestões de data para Maio.

Feedbacks mais do que bem-vindos, sempre!

[]s
Luciano Caixeta Moreira
luticm79@hotmail.com

segunda-feira, 6 de abril de 2009

Treinamento de SQL Server 2008 em São Paulo

Bom dia pessoal.
Eu estou conversando com o Fernando Garcia sobre a possibilidade de ficar alguns finais de semana em São Paulo, ministrando treinamentos sobre arquitetura do SQL Server, mecanismos internos, troubleshooting e tuning. Nessa nova fase eu estou trabalhando na criação de novos treinamentos, usando boas referências como base (livros da série inside, blogs, etc.), mas focado em um treinamento mais dinâmico, sem um pouco da burocracia dos MOCs.

Ainda estamos definindo preços e toda a logística, porém acreditamos que se fecharmos uma turma com pelo menos 8~10 alunos minha presença por lá se torna factível. Você mora em São Paulo e possui interesse em participar? Se sim, mande um e-mail para mim ou para o Fernando, que iniciou uma enquete no site MCDBA Brasil (http://www.mcdbabrasil.com.br/modules.php?name=Forums&file=viewtopic&p=13083#13083).

Lembrando que o foco do treinamento é para profissionais que já possuam experiência com o SQL Server.

[]s
Luciano Caixeta Moreira
luticm79@hotmail.com

Live Writer + Blogger

Estou numa briga sem fim com o Live Writer e Blogger. Eu formato direitinho o meu post no Live Writer e quando vou publicar aqui, a formatação vai toda embora, aparece alguns espaçamentos malucos, enfim, gasto mais um bom tempo reformatando o meu post. Alguém sabe de alguma fórmula para configurar essa dupla dinâmica?

Nossa, aproveitando que esse é um post de cunho pessoal, hoje o dia está zicado. Meu alarme não despertou e cheguei atrasado no curso (odeio falta de pontualidade, queria me surrar por ter colaborado com essa mania brasileira), saí correndo e na pressa de estacionar, dei um toque em uma moto que caiu e ainda raspou em outro carro, coisa boba, mas morri em quase R$ 150,00, mandei para a turma um e-mail com o arquivo errado e minha máquina ainda começou a apresentar umas maluquices, sem contar que a droga do Outlook Connector resolveu não funcionar nem com oferenda... Ainda vou jogar futebol hoje de noite, será que vou me machucar e mandar o joelho já bichado para outra cirurgia? Cadê a madeira... XÔ ZICA!! Fiquei o dia inteiro lembrando do Garfield... Segunda-feira!


[]s
Luciano Caixeta Moreira
luticm79@hotmail.com

Filtro no WHERE ou ON?

Continuo ministrando um treinamento e gostaria de deixar aqui um comentário bacana que apareceu hoje na aula. Estava comentando sobre o JOIN e a possibilidade de se usar filtros específicos na cláusula ON.

Para o exemplo eu me baseei no Northwind e executei duas consultas “diferentes”:

1:  SELECT
2: P.CategoryID,
3: P.ProductName,
4:
C.CategoryName,
5:
P.UnitPrice
6:
FROM Products AS P
7: INNER JOIN Categories AS C
8:
ON P.CategoryID = C.CategoryID
9:
and P.UnitPrice > 30
1:  SELECT
2:
P.CategoryID,
3:
P.ProductName,
4:
C.CategoryName,
5:
P.UnitPrice
6:
FROM Products AS P
7:
INNER JOIN Categories AS C
8:
ON P.CategoryID = C.CategoryID
9:
where P.UnitPrice > 30
Notem que a diferença está onde eu especifiquei o filtro do preço, através da cláusula ON do INNER JOIN ou da cláusula WHERE. Olhando sob a perspectiva do processamento lógico na segunda consulta, imaginamos um inner join sendo executado entre as duas tabelas e na tabela virtual resultante da junção, o filtro unitprice > 30 sendo aplicado.

Como processamento lógico é diferente do processamento físico, o SQL Server aplica o mesmo plano de execução (figura 01) para ambas as consultas, aplicando o filtro durante o clustered índex scan da tabela de produtos. Esse é um comportamento esperto do SQL Server, pois restringe o número de registros que irão fluir entre os passos do plano de execução, gerando tabelas virtuais menores.


clip_image002


(Figura 01 – plano de execução com INNER JOIN)

Explicado esse ponto, eu já partia para o próximo slide quando um aluno mencionou um caso muito importante. Ele disse “eu já fiz algo semelhante quando estava trabalhando com um OUTER JOIN e obtive resultados diferentes”. Ele não poderia estar mais certo, vamos supor as duas consultas abaixo.

SELECT
P.CategoryID,
P.ProductName,
C.CategoryName,
P.UnitPrice
FROM Products AS P
LEFT OUTER JOIN Categories AS C
ON P.CategoryID = C.CategoryID
WHERE P.UnitPrice > 30

SELECT
P.CategoryID,
P.ProductName,
C.CategoryName,
P.UnitPrice
FROM Products AS P
LEFT OUTER JOIN Categories AS C
ON P.CategoryID = C.CategoryID
AND P.UnitPrice > 30



Na primeira consulta o SQL Server retorna todos os 77 produtos existentes no Northwind e após realizar o join, que eventualmente poderia trazer um registro sem categoria (que não atendeu a cláusula P.CategoryID = C.CategoryID), aplica o filtro UnitPrice > 30, que somente permite que 24 registros sejam retornados.

Já no segundo caso, o SQL Server aplica o filtro composto que une as duas tabelas e como resposta do “inner join”, somente retorna 24 registros que atendem a condição. Porém, como estamos falando de um LEFT OUTER JOIN, que também retorna os registros da tabela da esquerda que NÃO atenderam a cláusula descrita, o SQL Server preserva a tabela Products, retornando os 77 registros, sendo 53 com nome da categoria como NULL (veja figura 02). Note que aqui o filtro está sendo aplicado no join e não no cluster index scan da tabela de produtos.

WHEREON_02

(Figura 02 – Plano de execução com OUTER JOIN e filtro no ON)

Quando estamos falando de um OUTER JOIN, a semântica de aplicar um filtro na cláusula WHERE ou no ON é diferente do INNER JOIN, então você deve ficar atento para não introduzir pequenos bugs no seu código.

[]s
Luciano Caixeta Moreira
luticm79@hotmail.com

sexta-feira, 3 de abril de 2009

Troubleshooting - Development Storage e Azure Tables (a solução)

Esse artigo é continuação da primeira parte da minha saga com as tabelas no Azure (http://luticm.blogspot.com/2009/04/troubleshooting-development-storage-e.html)
Depois de analisar muito código e estudar a estrutura do cabeçalho e outras coisinhas relacionadas com o Lite Shared Key, eu saí do computador, respirei um pouco e iniciei outro projeto do zero, onde reconstruí a aplicação, copiando e colando o código do meu artigo de referência.

Depois de tudo montado, fui executar e ... funcionou! Mas que droga, que besteira eu estou fazendo? Code Review, lá vamos nós.

Opa! Eu tinha optado por não herdar minha entidade da classe TableStorageEntity e durante o CTRL+C / CTRL+V eu não levei o campo Timestamp. Será que é isso? Coloquei o campo, usei o DevTableGen, chequei o gerenciamento dos serviços no development storage, executei minha aplicação e ... erro! Mas agora um erro diferente.

Vou poupá-los dos detalhes sórdidos da hora que se seguiu, mas quero alertá-los sobre algumas coisas que eu aprendi, e quem sabe ajudá-los a poupar um pouco de tempo e paciência.

1 – Apesar de não listado neste documento http://msdn.microsoft.com/en-us/library/dd320275.aspx, o Azure na nuvem se vira automaticamente com a coluna timestamp, enquanto é necessário criar a coluna para o ambiente de desenvolvimento local. A documentação do SDK fala sobre a necessidade de existência dos campos, mas não especifica esse detalhe “These system properties are automatically included for every entity in a table. The names of these properties are reserved and cannot be changed. The developer is responsible for inserting and updating the values of PartitionKey and RowKey. The server manages the value of Timestamp, which cannot be modified.”.

O que me fez gastar um tempão foi a mensagem do warning registrado no log, que me colocou na trilha errada.

2 – Recriar a estrutura da tabela e metadados.

Outro detalhe que pode te ajudar durante o desenvolvimento é a configuração da tabela no SQL Server. Veja os passos que eu executei para realizar outros testes:

2.1) Depois que eu deixei o código funcionando, alterei o nome dos campos da entidade de Address e Name para CampoA e CampoB.
2.2) Apaguei o banco de dados no SQL Server e recompilei minha solução, para atualizar a ddl com os novos nomes.
2.3) Executei novamente o comando DevTableGen para gerar o banco de dados e a tabela com os novos campos. Verifiquei no Management Studio, tudo criado corretamente.
2.4) Chequei o status dos serviços no development storage. Todos os serviços rodando e apontando para o local correto (vide figura abaixo).

clip_image002
2.5) Executei a aplicação e ... Mais um erro!

clip_image004

Muito estranho, o código está atualizado, a estrutura da tabela no SQL Server também já reflete o CampoA, mas porque estou recebendo esse erro?

Depois de analisar um pouco o que estava acontecendo, supus a causa raiz. O problema está com os metadados armazenados pelo serviço do development storage, que os manteve em cache e mostra corretamente o status de running, pois o banco de dados e a tabela existem, mas sem nenhum refresh do esquema.

Quando tentamos recuperar a propriedade CampoA, o serviço não consegue fazer o mapeamento com os seus metadados e retorna um erro, mesmo com a estrutura correta criada no banco de dados. Um simples restart do serviço de tabela trás os novos metadados e deixa a aplicação funcionando corretamente.

Então fica a dica: quando estiver desenvolvendo em seu ambiente local, depois de usar o DevTableGen, não esqueça de reiniciar o serviço de armazenamento das tabelas, para que os metadados sejam atualizados.

Depois que os problemas estão resolvidos você olha para trás e pensa: putz, quanta besteira, eu devia ter conseguido resolver isso em 10 minutos. Mas desenvolvimento é assim, ainda mais quando estamos com CTPs.

Espero que esse post ajude algum desenvolvedor desamparado. :-)

Até o próximo post.

[]s
Luciano Caixeta Moreira
luticm79@hotmail.com
luciano.moreira@srnimbus.com.br

Troubleshooting - Development Storage e Azure Tables (o problema)

Hoje gastei um bom tempo fazendo troubleshooting de um bug que eu introduzi no meu código, enquanto tentava manipular tabelas no Azure. A coisa começou obscura, através das mensagens de erro eu fui para um caminho ruim e somente depois de muitos testes consegui resolver meu problema e entender melhor alguns detalhes das ferramentas do Azure SDK para desenvolvimento local.

Para me orientar na criação de tabelas no Azure, utilizei o artigo http://blogs.msdn.com/jnak/archive/2008/10/28/walkthrough-simple-table-storage.aspx, de onde fui pegando algumas idéias e montando meu próprio exemplo.

Montei meu exemplo com uma tabela entidade simples e dois botões, responsáveis por inseriam um registro e fazer uma consulta nos registros. Rodei o aplicativo e bang! Apareceu aquela mensagem excelente “The Server encountered na error processing the request. See Server logs for more details”.

clip_image002

Fui então procurar onde ficam os logs do Development Storage e usando o .NET Reflector descobri que ficam no AppData local do usuário. Tarefa que seria mais rápida se eu tivesse lido o comentário do arquivo DevelopmentStorage.exe.Config. “The logs go to LOCALAPPDATA%\DevelopmentStorage\Logs and are named after the date/time when the development storage was started.” :-)

Analisando o diretório, adivinha? Vazio! Então alterei a configuração para trabalhar com o nível de logging detalhado (verbose).

  <system.diagnostics>
<sources>
<source name="System.Net.HttpListener" switchName="detalhado" >
<listeners>
<add name="defaultListener"/>
</listeners>
</source>
</sources>
<switches>
<!-- <add name="default" value="Critical"/> -->
<add name="detalhado" value="Verbose"/>
</switches> (continua...)

Agora sim, reiniciei o development storage para ele utilizar a nova configuração e após reproduzir o erro consegui ver o seguinte (extraí um pedaço do log):

System.Net.HttpListener Information: 0 : [5156] HttpListenerContext#64537591::.ctor(httpListener#6503226 requestBlob=35055504)
System.Net.HttpListener Information: 0 : [5156] HttpListenerRequest#3338611::.ctor(httpContext#64537591 memoryBlob# 35055504)
System.Net.HttpListener Information: 0 : [5156] Associating HttpListenerRequest#3338611 with HttpListenerContext#64537591
System.Net.HttpListener Information: 0 : [5156] HttpListenerRequest#3338611::.ctor(httpContext#64537591 RequestUri:http://127.0.0.1:10002/devstoreaccount1/Tabela() Content-Length:0 HTTP Method:GET)
System.Net.HttpListener Information: 0 : [5156] HttpListenerRequest#3338611::.ctor(HttpListenerRequest Headers: x-ms-date : Fri, 03 Apr 2009 14:30:15 GMT
DataServiceVersion : 1.0;NetFx
MaxDataServiceVersion : 1.0;NetFx
Accept : application/atom+xml,application/xml
Accept-Charset : UTF-8
Authorization : SharedKeyLite devstoreaccount1:5YEL7oTeEAsOtPyqxwBN9P8OBR4cw/DelOyy1Nk9+1M=
Host : 127.0.0.1:10002)

System.Net.HttpListener Warning: 0 : [5156] HttpListener#6503226::HandleAuthentication() - Recebida uma solicitação com um esquema de autenticação sem correspondência ou sem nenhum esquema desse tipo. AuthenticationSchemes:Anonymous, Authorization:SharedKeyLite devstoreaccount1:5YEL7oTeEAsOtPyqxwBN9P8OBR4cw/DelOyy1Nk9+1M=.

System.Net.HttpListener Verbose: 0 : [5156] HttpListener#6503226::EndGetContext(IAsyncResult#26998456)
System.Net.HttpListener Verbose: 0 : [5156] HttpListener#6503226::EndGetContext(HttpListenerContext#64537591 RequestTraceIdentifier#00000000-0000-0000-0500-0080010000f2)

Nota: estou tentando vencer meu preconceito e trabalhar com um SO em português, mas acho que vou acabar vencido nessa disputa...

Pelo log não encontrei nenhum erro, apenas um aviso – em negrito que aponta para um problema de autenticação, no meu entender, claro. Dado que existe uma série de diferenças entre o armazenamento de tabela no Azure e no desenvolvimento local (ref.: http://msdn.microsoft.com/en-us/library/dd320275.aspx), sendo uma delas “The local Table service supports only Shared Key Lite authentication. It does not support Shared Key authentication.”, tudo indicava um problema com o Shared Key Lite.

Com o intuito de confirmar minhas suspeitas, fiz um teste usando o serviço de armazenamento da minha conta no Azure. Diferente do local, onde tenho que usar a ferramenta DevTableGen, adicionei mais um botão à minha aplicação, responsável por criar uma tabela em tempo de execução:

StorageAccountInfo account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration();
TableStorage.CreateTablesFromModel(typeof(ContextoServico), account);
Resultado: tudo funcionando perfeitamente com o armazenamento na nuvem.

Pensei comigo “estou no caminho certo, vamos ver onde está o problema com os mecanismos de segurança do meu armazenamento local”...

Será?

[]s
Luciano Caixeta Moreira
luticm79@hotmail.com

quarta-feira, 1 de abril de 2009

Artigo publicado na .NET Magazine

No ano passado eu escrevi um artigo sobre o Synchronization Framework para a .NET Magazine e somente fui ver hoje que o artigo foi publicado na última edição!

Aqui está uma listagem dos artigos da edição: http://www.devmedia.com.br/resumo/default.asp?site=1

Bem legal, depois eu vou ver a revista para ver como ficou o resultado do artigo impresso.

[]s
Luciano Caixeta Moreira
luticm79@hotmail.com

SQL Server com TCP/IP, SQL ANSI e Truncate

Hoje cedinho eu comecei a ministrar um treinamento de SQL Server e o primeiro capítulo foi dedicado a uma visão geral da arquitetura do SQL Server e processamento lógico/físico das consultas. Sendo um treinamento de querying, será interessante revisitar alguns tópicos e tentar mostrar para a turma, de maneira acessível, como podemos escrever nossas consultas de forma limpa e eficiente. Depois de pegar um pouco de bagagem com o SQL Server, esse curso sobre consultas será uma experiência bem interessante (difícil é conter o lado geek e não sair entrando em detalhes…). Abaixo alguns pontos discutidos hoje…

1) Otimização da configuração do TCP/IP

Pergunta: “Como podemos fazer para otimizar o nosso canal de comunicação? É possível usarmos UDP ao invés do TCP”?
Resposta: Sendo UDP uma proposta inviável para a comunicação com o SQL Server, ele somente é utilizado pelo serviço de browsing. Me lembrei de uma otimização para o Windows 2003, relacionada com o TCP/IP chimney offload, descrito neste post: http://blogs.msdn.com/psssql/archive/2008/10/01/windows-scalable-networking-pack-possible-performance-and-concurrency-impacts-to-sql-server-workloads.aspx 

Também sabemos de algumas melhores práticas normalmente relacionadas com a configuração do seu cluster, mas não me lembro de bate pronto de um documento específico sobre o tuning de TCP/IP com SQL Server. Concordo que temos que atentar para a configuração de rede e garantir que não têm ninguém no meio do caminho perdendo pacotes TCP/IP e causando o reenvio destes, o que atrasaria o tempo total de execução de uma consulta na visão do cliente, mas vejo uma abordagem mais eficiente para esse tipo de cenário. Uma solução bem arquitetada que minimiza a conversa entre o cliente/servidor, somente transfere os dados necessários e evita um canal “chatty”, é uma abordagem mais eficiente para se manter um ambiente com bom desempenho do que simplesmente ficar fazendo pequenos ajustes em registros obscuros. Concordam?
Recomendo um outro blog muito bacana: http://blogs.msdn.com/sql_protocols

2) SQL ANSI

O SQL Server 2008 não é totalmente ANSI compliant com a especificação SQL ANSI 2003 mas, segundo bibliografia, ele implementa uma série de funcionalidades importantes (simples assim). Gosto de padrões e das observações no wikipedia http://en.wikipedia.org/wiki/SQL, mas com o amadurecimento das tecnologias eu não acho que os projetos devam ser desenvolvidos somente usando SQL ANSI X, para tentar garantir uma eventual portabilidade para outros SGBDRs, que na minha experiência raramente acontece. Se quer ficar independente do banco de dados, procure uma tecnologia de mapeamento objeto-relacional (ou monte o seu framework) que crie essa abstração, analisando os prós e contras.

3) Truncate Table – DDL ou DML?

Pergunta: “O truncate table é uma instrução de DDL ou DML?”
Resposta: Não sei, mas em um primeiro momento eu diria DML, pois envolve manipulação dos dados. Depois de uma pesquisa rápida, um aluno tirou a dúvida e o truncate é uma instrução DDL.
Aqui está uma boa referência: http://weblogs.sqlteam.com/mladenp/archive/2007/10/03/SQL-Server-Why-is-TRUNCATE-TABLE-a-DDL-and-not.aspx. Sua vida não muda em nada, mas fica aqui a curiosidade.

Até um próximo post…

[]s
Luciano Caixeta Moreira
luticm79@hotmail.com