Servidores de Aplicação

Autor: Vidal Martins - GPT   

Resumo

Continuando a nossa série de artigos sobre a caminhada da CELEPAR rumo às tecnologias de objetos e componentes distribuídos, hoje falaremos sobre servidores de aplicação. Além de explicarmos o que isso significa, descreveremos com um nível razoável de detalhes um tipo de componente de software comumente utilizado nesses servidores, chamado monitor de transação. Suas funcionalidades são indispensáveis em sistemas corporativos que possuem requisitos de escalabilidade e robustez.

Apresentação

Um servidor de aplicação é uma plataforma sobre a qual roda a porção servidora de um aplicativo. Isto inclui hardware e software. O hardware está fora do escopo deste artigo, mas o software pode ser dividido em dois grupos: funções do negócio, que são específicas para um domínio de problema; e serviços especializados, que são funções genéricas aplicáveis a diversas soluções.

Assim sendo, do ponto de vista do software um servidor de aplicação consiste de um agrupamento de funções de negócio e de serviços que integrados satisfazem as necessidades dos usuários. Embora existam diversos serviços disponíveis atualmente em forma de componentes de software, nos concentraremos em dois deles que consideramos de suma importância para o desenvolvimento de aplicações robustas e escaláveis: monitoramento de transações e gerenciamento de filas de requisições.

Esses serviços podem estar implementados em diversos tipos de produtos, como por exemplo monitores de transação [1,7,8,9] gerenciadores de transação entre objetos (OTM – Object Transaction Manager), serviço de transação dos ORBs [4,5,6], middleware orientado a mensagem (MOM – Message Oriented Middleware) [7], serviço de eventos dos ORBs [4,5,6] e extensões do sistema operacional.

Um monitor de transação moderno suporta transações entre objetos e gerenciamento de filas também. Por essa razão, uma análise mais aprofundada desse tipo de produto nos permitirá compreender como é possível adicionar robustez e escalabilidade a uma solução.

Comecemos pelo conceito: um monitor de transações é um produto de software utilizado para criar, executar e gerenciar aplicações de processamento transacional. Entre as suas principais funcionalidades podemos destacar:

  • Roteamento de transações;

  • Reinicio das transações após a ocorrência de falhas;

  • Balanceamento da carga de trabalho do servidor;

  • Garantia das propriedades ACID (Atomicidade, Consistência, Isolamento e Durabilidade) de uma transação [1,2,8,9];

  • Implementação do protocolo two-phase commit, que garante a atomicidade de uma transação envolvendo diversos programas ou computadores independentes [1,2,8,9];

  • Gerenciamento de comunicações cliente/servidor de vários tipos: request-response, queuing, conversations, publish-and-subscribe e broadcast [1,2,8].

Todas essas funcionalidades reunidas em um único produto proporcionam uma melhoria substancial de performance e contribuem significativamente para a produção de sistemas distribuídos robustos e escaláveis.

Discutiremos um pouco mais a fundo esse componente arquitetural pré-fabricado sob cinco enfoques: a importância dos monitores de transação; a arquitetura dos monitores de transação; como um monitor de transação contribui para a escalabilidade; como um monitor de transação contribui para a robustez; e um comparativo entre sistemas gerenciadores de bancos de dados e monitores de transação.

1. A importância dos monitores de transação

A performance é um aspecto crítico de sistemas transacionais. Ninguém está disposto a esperar mais do que poucos segundos para saber se existe poltrona disponível num vôo. É um grande desafio configurar um sistema para atender aos requisitos de tempo de resposta e de produtividade a um custo mínimo, pois existem muitas opções de produtos disponíveis.

Por esse motivo, os vendedores que atuam no mercado de processamento transacional formaram um consórcio independente chamado Transaction Processing Performance Council (TPC) [1,8,9,10], o qual definiu os primeiros benchmarks de sistemas transacionais que poderiam ser usados para comparar de forma justa diferentes produtos de diferentes vendedores. Cada benchmark do TPC utiliza programas transacionais padronizados e define a performance do sistema como sendo sua capacidade de processamento (throughput) diante de condições predeterminadas de carga de trabalho (workload), de tamanho do banco de dados, de tempo de resposta e assim sucessivamente. Há duas medidas principais para a performance de um sistema: o throughput máximo, medido em transações por minuto (tpm), e o custo das transações, medido em dólares por tpm ($/tpm). O custo é calculado como o preço de tabela dos produtos de hardware e software necessários, mais cinco anos de manutenção desses produtos (chamadado custo de propriedade).

Os dois primeiros benchmarks, chamados TPC-A e TPC-B, modelaram uma aplicação de automação de caixa eletrônico (automated teller machine), mas esses benchmarks foram aposentados e substituídos pelo TPC-C. TPC-A e TPC-B são muito simplistas comparados à maioria das aplicações transacionais atuais. Além disso, quase todos os fabricantes têm números de benchmark TPC-A/B tão bons que estes índices não representam mais um bom diferencial entre os produtos a serem selecionados.

O TPC-C é baseado numa aplicação de entrada de pedidos para um fornecedor de produtos no atacado. Comparado ao TPC-A/B, ele inclui uma maior variedade de transações, algumas bastante pesadas, e um banco de dados mais complexo.

O tamanho do banco de dados é proporcional ao número de depósitos de produtos. Há cinco tipos de transação:

  • Registro de novos pedidos;

  • Pagamento de pedido;

  • Consulta à situação de um pedido;

  • Entrega do pedido;

  • Consulta ao nível de estoque.

As três primeiras transações têm requisitos rígidos de tempo de resposta. A transação de "entrega do pedido" executa como um batch periódico e a transação de "consulta ao nível de estoque" tem requisitos de tempo de resposta e consistência mais flexíveis. Com relação à carga de trabalho, exige-se um número igual de transações do tipo "registro de novo pedido" e "pagamento de pedido", e para cada 10 novos pedidos processados exige-se uma transação do tipo "consulta à situação de um pedido", "entrega de pedido" e "consulta ao nível de estoque".

O TPC-C apresenta maior disputa pelos dados compartilhados e exercita uma variedade mais ampla de funções sensíveis à performance, tais como execução de transações a posteriori, acesso via chave secundária e cancelamento de transações (abort).

Mas, por que o interesse nos testes TPC? Simplesmente para reforçar a importância dos monitores de transação. Todas as soluções de alta performance divulgadas pelo TPC [10], sem exceção, utilizam monitores de transação. A tabela abaixo mostra os 10 primeiros classificados em ordem de throughput (tpmC). A segunda tabela mostra os 10 primeiros classificados com base no custo da transação ($/tpmC). Os dados contidos nessas tabelas foram coletados em 25/11/1998.

No

Cia.

Configuração

tpmC

$/tpmC

1

Digital

AlphaServer 8400 (8 node x 12-way)

102.541,85

$139,49

2

Sequent

NUMA-Q 2000 E300 (64-way)

93.900,85

$131,67

3

IBM

RS/6000 SP Model 309 (12 node x 8-way)

57.053,80

$147,40

4

Sun

Enterprise 6500 (24-way)

53.049,97

$76,00

5

HP

HP 9000 V2250 (16-way)

52.117,80

$81,17

6

Sun

Ultra Enterprise 6000 c/s (2 node x 22-way)

51.871,62

$134,46

7

Sequent

NUMACenter 2000 (32-way)

48.793,40

$127,53

8

IBM

AS/400e 9406-S40 (12-way)

43.169,85

$128,91

9

HP

HP 9000 V2200 (16-way)

40.794,36

$103,43

10

HP

HP 9000 V2200 (16-way)

39.469,47

$94,18

 

 

No

Cia.

Configuração

$/tpmC

tpmC

1

Compaq ProLiant 7000 c/s (4-way)

$18,76

22.478,90

2

Compaq ProLiant 5500 6/400

$21,71

17.715,90

3

Unisys Aquanta QS/2V (4-way)

$22,11

19.118,37

4

Unisys Aquanta QR/2V (4-way)

$22,19

19.118,37

5

Compaq ProLiant 7000 c/s (4-way)

$22,50

19.725,10

6

HP NetServer LH 4r (4-way)

$23,10

19.050,17

7

Unisys Aquanta QR/2 (4-way)

$23,73

21.354,55

8

Unisys Aquanta QR/2 (4-way)

$24,83

18.343,17

9

Unisys Aquanta QS/2 (4-way)

$25,49

18.154,00

10

IBM Netfinity 7000 M10 (4-way)

$25,70

22.459,80

O TPC-C é um benchmark para sistemas transacionais. Existe também o TPC-D, um benchmark que modela um ambiente de apoio a decisão no qual consultas ad hoc complexas são executadas sobre grandes bancos de dados. As consultas geralmente apresentam uma ou mais das seguintes características:

  • Join entre múltiplas tabelas;

  • Classificação intensa;

  • Agrupamento e agregação;

  • Varreduras seqüenciais.

O propósito do TPC-D é avaliar custo e performance de sistemas que suportam esse tipo de aplicação.

2. A arquitetura dos monitores de transação

Um monitor de transação implementa seu fluxo de controle utilizando o conjunto de componentes de software ilustrados na figura abaixo [8].

2.1. Presentation Server

A estação de trabalho interage com o componente chamado presentation server (servidor de apresentação), o qual é responsável pela tradução das telas, das seleções de menus, e de outros tipos de entradas em uma mensagem de formato padrão (requests). Serviços de apresentação estão sendo fornecidos cada vez mais por linguagens de quarta geração, tais como Visual Basic, PowerBuilder e Delphi.

A requisição proveniente do servidor de apresentação pode ser temporariamente armazenada em disco numa fila, ou pode ser redirecionada diretamente para ser processada pelo componente chamado workflow controller (controlador de fluxo de trabalho). Este componente roteia a requisição para o servidor de transação apropriado e invoca um programa desse servidor, o qual realiza o trabalho solicitado, isto é, o qual executa realmente a transação [8].

Os primeiros monitores de transação tinham um servidor de apresentação nativo para executar a interface com o usuáro. Nos anos 80, produtos independentes para gerenciamento de interface tornaram-se populares, os quais ofereciam ambientes de construção de formulários do tipo wysiwig (what you see is what you get, ou o que você vê é o que você obtém) e chamavam funções de uma linguagem de programação padrão.

Quando utilizamos um gerenciador de formulários que não está totalmente integrado com o servidor de apresentação, o programador da aplicação precisa fazer chamadas para este servidor que construirá a requisição. Isto é comum quando se utiliza linguagens de quarta geração cliente/servidor e gerenciadores de formulários projetados para interagir com dispositivos especializados, tais como leitoras de códigos de barras, terminais de autorização de cartões de crédito, caixas registradoras, bombas de combustível, robôs, ATMs e assim por diante.

2.2. Workflow Controller

O propósito principal do controlador de fluxo de trabalho é mapear as requisições recebidas para servidores de transação capazes de executá-las e enviar essas requisições aos respectivos servidores. Se a transação produz algum tipo de saída, o controlador de fluxo é responsável por rotear essa resposta novamente para o servidor de apresentação que enviou a requisição. Normalmente, a camada de controle de fluxo executa as operações Start, Commit e Abort. Dentro da transação poderá haver chamadas para um ou mais servidores de transação.

Outras responsabilidades importantes do controlador de fluxo são as seguintes: interação com o serviço de diretório; roteamento de requisições baseada em parâmetros; gerenciamento de sessões e segurança; minimização das sessões de comunicação; coordenação de transações aninhadas; tratamento de erros; finalmente, gerenciamento de pontos de salvamento de trabalhos parcialmente realizados (savepoints).

2.3. Transaction Server

Um servidor de transação é um programa da aplicação que realmente executa a requisição. Pode ser um programa interno, ou pode chamar outros programas para realizar seu trabalho. Esses outros programas podem executar no mesmo ambiente do servidor de transação ou em um sistema remoto, caso em que uma mensagem de comunicação é necessária entre o módulo chamador e o módulo chamado.

Os servidores de transação não podem ser considerados programas comuns de acesso a dados por dois motivos: eles necessitam atender altas taxas de requisição e precisam também suportar comunicações baseadas em transações.

Realizar comunicação dentro do contexto de uma transação não é uma tarefa fácil, por duas razões. Primeiro, se você inicia uma transação em um processo, tal como o controlador de fluxo, e então envia uma mensagem para outro processo, como um servidor de transação, a este último precisa ser dito que ele está operando na mesma transação que aquele que o chamou. Segundo, todos os processos que foram envolvidos na transação devem ser informados quando há o comprometimento (commit) da transação ou seu cancelamento (abort). Uma grande parte do trabalho de um monitor de transações está dedicada a essas atividades.

3. Como um monitor de transação contribui para a escalabilidade

Ao explicar a arquitetura de um monitor de transações, dissemos que o workflow controller é responsável, entre outras coisas, por minimizar o número de sessões de comunicação. Como isso acontece? Suponha que existissem 300 servidores de apresentação e 50 servidores de transação em um determinado sistema, conforme mostra a figura a seguir [8]. Quantas sessões seriam necessárias para permitir que qualquer servidor de apresentação acessasse qualquer servidor de transação? 300 x 50 = 15.000 sessões.

Isto significa que o modelo 2-camadas gera uma explosão polinomial de sessões. Como evitar essa explosão? Colocando-se controladores de fluxo de trabalho entre os servidores de apresentação e os servidores de transação, ou seja, implementando o modelo 3-camadas. Considere os mesmos números anteriores, 300 clientes e 50 servidores. Acrescente 10 controladores de fluxo, cada qual conectado com todos os servidores de transação, conforme mostra a figura a seguir [8].

Dentro desta nova arquitetura, quantas sessões seriam necessárias para permitir que qualquer servidor de apresentação acessasse qualquer servidor de transação? Não existe uma resposta exata para essa pergunta, em virtude da distribuição de funcionalidades entre os controladores de fluxo. Se todos eles possuírem as mesmas funções, cada servidor de apresentação só precisa estar conectado a um controlador de fluxo para ter acesso a todas as transações disponíveis no sistema. Por outro lado, se cada função estiver disponível apenas em um único controlador de fluxo, então cada servidor de apresentação precisa estar conectado a todos os controladores de fluxo simultaneamente para ter acesso a todas as transações do sistema. Obviamente, seria possível criar configurações intermediárias nas quais algumas funções estivessem repetidas em diversos controladores de fluxo e outras fossem exclusivas. Mas, para efeito de cálculo podemos nos concentrar nos dois casos extremos descritos inicialmente. O primeiro, que exige apenas uma conexão em cada servidor de apresentação, nos levaria a um total de 800 conexões (300 entre servidores de apresentação e controladores de fluxo, mais 500 (10 X 50) entre controladores de fluxo e servidores de transação). O segundo caso, que exige 10 conexões em cada servidor de apresentação nos levaria a um total de 3500 conexões (3000 (300 X 10) entre os servidores de apresentação e os controladores de fluxo, mais 500 (50 X 10) entre os controladores de fluxo e os servidores de transação). Na pior das hipóteses haveria uma redução de cerca de 76% no número de conexões necessárias, e na melhor das hipóteses a economia seria de aproximadamente 94%. Note que em qualquer situação o monitor de transação seria capaz de reduzir drasticamente o número de sessões de comunicação e conseqüentemente de aumentar a escalabilidade do sistema.

Outra contribuição dos monitores de transação para a escalabilidade é a implementação de threads e server classes. A seguir, veremos porquê cada um desses recursos é importante. Começaremos pelas threads.

O sistema operacional não funciona bem com um número muito grande de processos por muitas razões, dentre as quais podemos destacar as seguintes: diversas funções do sistema operacional navegam sequencialmente pelas listas de processos; a troca de contexto entre processos implica a substituição de registradores e a recarga da memória cache; normalmente, cada processo necessita de uma quantidade de memória física que não pode ser paginada. Devido a esses problemas os vendedores de monitores de transação começaram a suportar processos multithreaded. Cada thread é um caminho de execução independente dentro do processo. Todas as threads de um processo executam o mesmo programa e usam a mesma memória, mas cada uma delas tem uma área privativa (save area) para armazenar seus registradores e suas variáveis locais (stack), conforme mostra a figura a seguir [8].

As threads economizam memória, evitam trocas de contexto e reduzem o número de processos. Elas podem ser implementadas pelo monitor de transação ou pelo sistema operacional. Quando são controladas pelo monitor de transação o sistema operacional não sabe que elas existem. Neste caso, se o servidor de transação tentar ler dados do disco ou mensagens de comunicação e esses dados ainda não estiverem disponíveis, o sistema operacional bloqueará o processo. Se existirem múltiplas threads executando dentro do processo todas elas serão temporariamente interrompidas. Isto é ruim, pois algumas threads poderiam realizar trabalho útil enquanto outras esperassem por operações de I/O.

Para evitar esse problema o monitor de transação tem que transformar operações de I/O síncronas em mensagens assíncronas para o disco, para o banco de dados ou para o sistema de comunicação, e tem que solicitar que seja gerada uma interrupção de software quando cada operação de I/O for completada. A vantagem deste modelo é o uso de multithreading, mas a desvantagem é que todas as chamadas para operações de I/O precisam ser interceptadas pelo monitor de transação. As versões iniciais do CICS para mainframe funcionavam dessa forma.

A outra alternativa é deixar que o sistema operacional controle as threads de um processo. Neste caso, quando uma thread executa uma operação de I/O síncrona o sistema operacional bloqueia a respectiva thread. Isto evita troca de contexto desnecessária e se o processo estiver executando em uma plataforma SMP (Symmetric Multiprocessor) ele pode distribuir suas threads para diferentes processadores, proporcionando paralelismo entre as threads do mesmo processo. Um problema desta alternativa é o overhead de performance. Uma vez que é o sistema operacional quem gerencia a execução das threads isto implica a utilização de system calls, que geralmente são mais caras que operações executadas a nível de usuário (o monitor de transações opera neste nível). Quando múltiplas threads executam dentro do mesmo processo existe pouca ou nenhuma proteção de memória entre elas. Um erro no processamento de uma thread pode comprometer a memória de todo o processo.

Resumindo, multithreading oferece melhorias significativas de eficiência, mas deve ser usado cuidadosamente para evitar bloqueio durante operações de I/O em disco, interferência entre o scheduling do monitor de transação e do sistema operacional, overhead de peformance na troca de contexto das threads e corrupção de memória desprotegida. Na maioria das aplicações, multithreading controlado pelo sistema operacional é superior ao controlado pelo monitor de transação, uma vez que evita os dois primeiros problemas desta lista e pode se beneficiar de configurações SMP.

Uma boa alternativa para processos multithreaded é usar diversos processos emulando um conjunto de threads, isto é, ao invés de ter um processo multithreaded, o sistema usa um conjunto de processos single-threaded, todos rodando o mesmo programa, conforme mostra a figura a seguir [8].

Esta técnica é chamada de server class porque é mais usada nos servidores de transação e sua principal característica é evitar as seguintes desvantagens de processos multithreading: tratamento especial para operações de I/O; conflitos de scheduling entre processos e threads; possibilidade de problemas provenientes de corrupção de memória; queda do processo como um todo em virtude da falha de uma thread (um processo de uma server class falha de forma independente dos demais). Quando se utiliza server classes é necessário um mecanismo adicional cujo objetivo é despachar as chamadas recebidas por uma server class para processos servidores específicos. Trata-se do balanceamento de carga entre os servidores da classe. Isto pode ser feito de diversas formas, como por exemplo:

O programa que despacha as chamadas pode randomizar a seleção do servidor, realizando desta forma um balanceamento pela média;

Os processos da server class podem compartilhar uma fila de requisições não processadas;

A server class pode ter um único processo para receber todas as requisições e roteá-las para processos ociosos.

Há pouco dissemos que muitos processos single-threaded poderiam resultar em problemas de performance e que a solução seria processos multithreaded. Por que estamos aceitando que os servidores de transação sejam implementados como múltiplos processos single-threaded? Porque o número de servidores de transação necessários é proporcional ao número de transações em execução e não ao número de estações de trabalho disponíveis.

Diante de todas as alternativas que foram apresentadas, com suas vantagens e desvantagens, podemos concluir que é possível otimizar a escalabilidade de um sistema implantando uma arquitetura 3-camadas, por meio de um monitor de transações, onde os servidores de apresentação e os controladores de fluxo sejam processos multithreaded e os servidores de transação sejam server classes.

4. Como um monitor de transação contribui para a robustez

No processamento transacional direto um cliente envia uma requisição para um servidor e espera de forma síncrona que este execute a transação e retorne uma resposta. Embora esse modelo seja amplamente utilizado na prática, ele apresenta algumas limitações que estão ilustradas na figura a seguir [8].

Queda do servidor durante o processamento da transação;

Queda do cliente durante o processamento da transação;

Balanceamento de carga ineficiente;

Não há possibilidade de impor prioridade no processamento das requisições.

Esses problemas podem ser solucionados por meio do uso de filas de requisições e de respostas entre o cliente e o servidor, conforme mostra a figura a seguir [8].

A fila é um recurso transacional, ou seja, as operações de armazenamento e consumo das mensagens da fila são efetivadas ou desfeitas dependendo da maneira que finaliza a transação na qual elas foram executadas (commit ou abort), de acordo com a ilustração a seguir [8]. Normalmente as filas são persistentes.

O modelo de processamento transacional baseado em filas resolve os problemas que foram apresentados anteriormente. Em primeiro lugar, o cliente pode enviar uma requisição mesmo que o servidor esteja ocupado, parado ou desconectado, bastando para isso que a fila esteja disponível. Se o servidor estiver disponível ele executa a requisição imediatamente. Segundo, o servidor pode enviar uma resposta para o cliente mesmo que ele esteja parado ou desconectado, bastando para isso que a fila de respostas esteja disponível. Terceiro, diversos servidores podem receber requisições da mesma fila, o que permite realizar um balanceamento de carga perfeito, pois as requisições pendentes permanecem dissociadas dos processos servidores até o momento de serem atendidas. À medida que os processos servidores terminam suas tarefas eles recorrem à fila para obter mais trabalho, aquele que estiver na vez. Quarto, a ordem das requisições na fila pode ser estabelecida de acordo com algum critério de prioridade. Para garantir que as requisições de baixa prioridade recebam algum nível de serviço pode-se dedicar a elas um processo servidor específico.

A implementação do modelo de filas exige que o sistema ou o monitor de transação possua um queue manager a fim de armazenar e gerenciar as filas. Um queue manager é muito semelhante a um sistema gerenciador de banco de dados. Ele deve realizar operações como criação e destruição de filas, e modificação dos atributos da fila (owner, tamanho máximo, privilégios dos usuários, etc.). Também deve suportar operações sobre os elementos das filas, tais como colocar na fila (enqueue), retirar da fila (dequeue), navegar pelos elementos da fila sequencialemente sem retirá-los dela e acessar aleatoriamente os elementos da fila. Os sistemas de filas também devem ser capazes de manter conexões persistentes com os usuários. Se o cliente perder a conexão com o gerenciador de filas, quando ele tentar reconectar o queue manager reestabelecerá a conexão já existente. Outra funcionalidade normalmente disponível é um esquema de roteamento de requisições bastante flexível. Por exemplo, é possível mover elementos de uma fila para outra de forma automática. Isto pode ser útil para garantir a comunicação entre o cliente e o servidor quando este estiver sobrecarregado ou mesmo fora do ar. Também pode ser usado para reunir as requisições de um sistema e enviá-las mais tarde, em lote, para outro sistema.

Técnicas de gerenciamento de filas são importantes para processar requisições que exigem a execução de mais de uma transação. Esses processamentos multitransacionais são normalmente chamados de workflows. Um workflow consiste de vários passos e cada passo executa como uma transação. É iniciado por uma requisição que é armazenada em uma fila. Cada passo do fluxo produz requisições para os passos subseqüentes. A requisição que iniciou o fluxo normalmente exige uma resposta para indicar ao usuário que o trabalho foi concluído. Entretanto, os passos intermediários não precisam gerar respostas para o usuário. A figura a seguir [8] representa um workflow multitransacional.

Após quebrar a execução de uma requisição em múltiplas transações não é mais possível obter os benefícios de transação única (ACID). Perde-se especificamente os benefícios de isolamento (serialização) e atomicidade (tudo ou nada). O problema de isolamento causado pelo workflow multitransacional normalmente exige uma solução que é específica da aplicação. Já o problema da atomicidade pode ser solucionado por meio de compensação automática. Usando essa abordagem, todas as transações de um fluxo multitransacional exceto a última têm uma transação de compensação associada, a qual é capaz de reverter o efeito da transação original, conforme mostra a figura a seguir [8].

A compensação automática ocorre da seguinte maneira. O sistema rastreia a seqüência de transações que deve executar. Se não for possível finalizar toda a seqüência, o sistema executa transações de compensação para todas aquelas que já rodaram, voltando ao seu estado inicial. Esse conceito exige que o programador de aplicação escreva o código de compensação correspondente a cada passo. Esse modelo é chamado de saga: conjunto de transações que roda completamente ou que executa transações de compensação para cada transação concluída no conjunto.

Um sistema robusto é aquele que está preparado para funcionar adequadamente, mesmo na presença de falhas. Acreditamos que as informações contidas nesta seção do artigo demonstram que o gerenciamento de filas de requisições, seja ele realizado por monitores de transações ou por softwares específicos, contribui fortemente para a robustez de um sistema transacional.

5. Servidores de banco de dados versus monitores de transação

Um servidor de banco de dados é um sistema gerenciador de banco de dados (SGBD) que oferece muitas das características de um monitor de transação. Em virtude dessas funcionalidades comuns, uma arquitetura de processamento transacional baseada em SGBDs muitas vezes é chamada de TP lite (processamento transacional leve).

Já que é possível realizar processamento transacional utilizando um SGBD, por que alguém deveria comprar um monitor de transação? A resposta é escalabilidade e algumas outras características.

Servidores de banco de dados implementam o modelo 2-camadas, ou seja, clientes falam diretamente com servidores multithreaded. Quando um grande número de clientes precisa se comunicar com um grande número de servidores, problemas de roteamento se tornam sérios. A solução é adicionar uma camada intermediária, tal como é oferecida por um monitor de transação. A arquitetura em 3-camadas é mais natural para suportar projetos de sistemas orientados a objetos, os quais consistem de regras de negócio que invocam objetos de negócio.

Com um servidor de banco de dados, é necessário escrever as aplicações utilizando stored procedures em uma linguagem proprietária (isto pode mudar quando o padrão SQL3 for amplamente adotado [11]). Geralmente, a linguagem de stored procedure não é tão expressiva como uma linguagem de propósito geral. Por exemplo, alguns sistemas não permitem que uma aplicação chame outra, algumas linguagens têm um conjunto limitado de tipos de dados, outras têm extensões de tipos de dados proprietárias. Além disso, é outra linguagem a ser aprendida além da linguagem de programação padrão, embora esse seja um problema que alguns monitores de transação também tenham.

Os servidores de banco de dados oferecem ferramentas limitadas de depuração e desenvolvimento. Já os monitores de transação geralmente utilizam linguagens compiladas que apresentam melhor desempenho em aplicações de computação intensiva.

Outra característica de diferenciação entre os dois ambientes é seu suporte a transações distribuídas. Sistemas de bancos de dados relacionais geralmente suportam transações distribuídas somente entre produtos do mesmo fabricante, enquanto os monitores de transação são capazes de gerenciar múltiplos produtos de bancos de dados. Além disso, os monitores de transação podem interagir também com outros tipos especializados de gerenciadores de recursos, tais como sistemas de arquivos orientados a registros e gerenciadores de filas.

A vantagem que obtemos utilizando um servidor de banco de dados é que os protocolos são ajustados para o sistema de banco de dados e por esse motivo podem ser mais rápidos. Por outro lado, os SGBDs oferecem apenas um paradigma de comunicação: requisição-resposta (request-response). Eles não oferecem comunicação ponto a ponto ou baseada em fila.

Um monitor de transação sabe que existem diferentes aplicações rodando em diferentes nós do sistema. Ele é capaz de priorizar aplicações, fazer controle de carga baseado na aplicação, resolução remota de nomes, e segurança baseada na aplicação, tarefas que seriam difíceis de realizar em um servidor de banco de dados.

A performance e as funcionalidades dos servidores de banco de dados estão melhorando muito, a tal ponto de eles talvez alcançarem os monitores de transação de baixo volume, mas a curto prazo não deve haver fusão entre essas duas tecnologias. A longo prazo tudo pode acontecer.

Resumindo a situação de concorrência entre essas duas tecnologias, poderíamos dizer que os SGBDs são suficientes para sistemas departamentais, onde a carga de trabalho não é muito elevada, os servidores são poucos e homogêneos e o número de usuários é pequeno. Porém, quando se trata de uma aplicação corporativa, situação na qual a complexidade tecnológica e os números são bem mais expressivos, a solução é o monitor de transação.

Referências Bibliográficas

[1] EDWARDS, J.; DEVOE D. 3-Tier Client/Server at work. New York : John Wiley, 1997.

[2] COULOURIS, G.; DOLLIMORE, J.; KINDBERG T. Distributed systems - concepts and design. Harlow : Addison Wesley, 1996.

[3] D’SOUZA, D. F.; WILLS, A. C. Objects, components and frameworks with UML: the catalysis approach. United States of America : Addison Wesley, 1998.

[4] ORFALI, R.; HARKEY, D.; EDWARDS, J. The essential distributed objects survival guide. New York : John Wiley, 1996.

[5] SIEGEL, J. CORBA fundamentals and programming. New York : John Wiley, 1996.

[6] OMG. Web site of Object Management Group. Disponível na Internet. http://www.omg.org.

[7] ORFALI, R.; HARKEY, D.; EDWARDS, J. The essential client/server survival guide. New York : John Wiley, 1996.

[8] BERNSTEIN, P. A.; NEWCOMER, E. Principles of transaction processing – for the systems professional. San Francisco : Morgan Kaufmann, 1997.

[9] GRAY, J.; REUTER, A. Transaction processing: concepts and techniques. San Francisco : Morgan Kaufmann, 1993.

[10] TPC. Web site of transaction processing performance council. Disponível na Internet. http://www.tpc.org.

[11] MELTON, J. Understanding SQL’s stored procedures: a complete guide to SQL/PSM. San Francisco : Morgan Kaufmann, 1998.