Páginas

terça-feira, 20 de setembro de 2011

Membros ThreadStatic e ASP.NET thread switching: cuidados ao usar

Tudo começou com uma dúvida referente como a classe TransactionScope mantém referência à um objeto de transação durante todo o seu escopo de atuação, mesmo quando são feitas chamadas à outros métodos sem a passagem explícita desse objeto de transação como um parâmetro desse método, por exemplo.

Olhando o código-fonte do TransactionScope através de ferramentas de disassembler, como o Redgate .NET Reflector ou Telerik JustDecompile (como eu amo esses aplicativos!), percebi que o contexto de transação é armazenado em um membro decorado com o atributo ThreadStatic, ou seja, é praticamente uma "variável global" esclusiva de uma thread, que não pode ser acessada por outra thread.



O problema ocorre quando trabalhamos no ASP.NET. Durante o processamento de uma página em ASP.NET, pode (leia-se: "pode", não que ocorrerá sempre!) uma mudança da thread atual (thread switching). Então, uma página que começa a ser processada pela thread 1 pode terminar com a thread 2! Quem define isso é a plataforma ASP.NET, que tenta dar um uso eficaz de recursos.

Bom, o meu medo era que uma aplicação ASP.NET usando TransactionScope pudesse gerar alguma inconsistência de banco de dados no momento que uma transação estivesse ativa e a thread eventualmente mudasse (http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx). 

Mas uma pesquisa na internet me mostrou que esse evento de troca de thread é menos comum de acontecer do que eu imaginava. Geralmente ele ocorre quando há algum processamento assíncrono, por exemplo, usando as funcionalidades do async no ASP.NET 2.0 (http://msdn.microsoft.com/en-us/magazine/cc163725.aspx) ou na inicialização da página. Ou seja, praticamente esse problema pode ocorrer num mal uso de processamento assíncrono no ASP.NET com TransactionScope: quem em sã consciência abriria uma transação durante um processamento assíncrono?

Por isso, fiquei mais tranquilo ao usar transações controladas pelo TransactionScope em aplicações ASP.NET. Mas claro, se eu precisar guardar alguma informação de contexto, usaria o HttpContext.Current.Items ao invés de um membro estático marcado com ThreadStatic.

Alguns links esclarecedores:
[]'s

Nenhum comentário:

Postar um comentário