Post on 29-Oct-2015
description
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 1/84
CENTRO PAULA SOUZA
FACULDADE DE TECNOLOGIA DE TAQUARITINGA
CURSO SUPERIOR DE TECNOLOGIA EM PROCESSAMENTO DE DADOS
CONTROLE DE TRANSAÇÃO UTILIZANDO O SPRINGFRAMEWORK
AUTOR: GUILHERME MAZZO PELUZZO
ORIENTADORA: PROF. JOÃO DE LUCCA FILHO
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 2/84
Taquaritinga, SP
2011
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 3/84
GUILHERME MAZZO PELUZZO
CONTROLE DE TRANSAÇÃO UTILIZANDO O SPRINGFRAMEWORK
Monografia apresentada à Faculdade de Tecnologia de Taquaritinga, como partedos requisitos para a obtenção do título de Tecnólogo em Processamento deDados.
Orientadora: Prof.João de Lucca Filho
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 4/84
Taquaritinga, SP
2011
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 5/84
Dedico,
À minha esposa e filho que me apoiaram ...........
AGRADECIMENTOS
Primeiramente a Deus, por ter me dado o sopro da vida e por estar presente em todos os momentos dela.
Aos meus pais, pelo amor incondicional que deram à mim, mesmo quando todas as circunstâncias levavam a
crer que não haveria saída.
À minha avó Neusa, pelo amor imenso e carinho que teve comigo e com meus irmãos durante a nossa
infância.
Aos meus irmãos, por serem meus melhores amigos e companheiros. Por estarem por perto nas melhores e
nas piores horas.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 6/84
Aos professores que, desde quando ingressei na vida acadêmica, estimularam o meu desenvolvimento e,
assim, moldaram boa parte do que sou hoje.
Cabe aqui também um agradecimento especial a algumas pessoas que me proporcionaram lições
impressionantes, tanto pessoal quanto profissionalmente: Alan Teodoro, Thaysa Bello, Angelo Satelite, Esdras
Barreto, Cleber Ramos, Oswaldo Mauricio Neto, João Amanti, Ivan Fabbri, Eduardo Ferreira, Tiago Pichonelli,
Addo Grossi, Rodrigo Malara, Marcos Selli, Paulo Paschoalino, Hebron Corso, Ricardo Camargo, Diony Rodrigues,
Vitor Santos, Ildebrando Cortonezi, Odazil Junior, Gustavo Silva entre outros.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 7/84
(epígrafe)
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 8/84
“Penso logo desisto.....”
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 9/84
PELUZZO; G.M. Controle de Transações utilizando Spring Framework. (Monografia). Centro Estadual DeEducação Tecnológica “Paula Souza”, Faculdade de Tecnologia de Taquaritinga, Taquaritinga, 79, 2011.
RESUMO
Este trabalho acadêmico mostrará uma visão geral sobre transações, Spring Framework e como implementar
o controle destas com este framework.
Na apresentação do Spring, dar-se-á uma atenção especial às suas duas funcionalidades mais importantes:
Injeção de Dependências e suporte à Programação Orientada a Aspectos. Este enfoque tem como objetivo principal
mostrar o mecanismo básico de funcionamento do framework e, posteriormente, facilitar o entendimento de como ele
controla as transações através de suas classes e interfaces.
No que diz respeito a transações, o trabalho explicará o significado de uma transação, suas propriedades e
também os modelos transacionais existentes. Haverá uma breve explanação sobre as bibliotecas Java responsáveis
pelo controle transacional e a apresentação de alguns padrões de projetos utilizados quando apresenta-se a
necessidade do controle de transação, bem como a aplicação destes em situações próximas à realidade da construção
de sistemas de informação.
Por fim, mostra-se as maneiras de se implementar o controle de transação utilizando o Spring Framework.
Palavras-chave: Transações, Java, Spring Framework, Controle de Transações
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 10/84
PELUZZO; G.M. Controle de Transações utilizando Spring Framework. (Monografia). Centro Estadual DeEducação Tecnológica “Paula Souza”, Faculdade de Tecnologia de Taquaritinga, Taquaritinga, 79, 2011.
ABSTRACT
This academic work will show an overview of transactions, Spring Framework and how to implement
such control with this framework.
Presenting the Spring, will give special attention to their two most important features: Dependency
Injection and support for Aspect Oriented Programming. This approach has as main objective to show the
basic mechanism of operation of the framework and then facilitate the understanding of how it manages
transactions through its classes and interfaces.
With regard to transactions, the work will explain the meaning of a transaction, their properties and
also the existing transactional models. There will be a brief explanation of the Java libraries responsible for
transaction control and presentation of some design patterns used when it presents the need for transaction
control, and the application of these in situations similar to the reality of building information systems.
Finally, it is shown the ways to implement the transaction control using the Spring Framework.
Keywords: Transactions, Java, Spring Framework, Transaction Management
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 11/84
SUMÁRIO
introdução 13
visão geral do Spring Framework 14
MODULOS DO SPRING FRAMEWORK 15
15
INJEÇÃO DE DEPENDÊNCIA 17
SUPORTE A PROGRAMAÇÃO ORIENTADA A ASPECTOS 23
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 12/84
Transações Java 26
O QUE É UMA TRANSAÇÃO? 26
QUAL A NECESSIDADE DE UMA TRANSAÇÃO 26
PROPRIEDADES DE UMA TRANSAÇÃO 26
PROCESSAMENTO TRANSACIONAL 28
MODELOS DE TRANSAÇÃO 28
JTA E JTS 44
PADRÕES DE PROJETO RELACIONADOS À TRANSAÇÕES 47
Controle de transação no spring framework 58
ESCOLHENDO UM GERENCIADOR DE TRANSAÇÕES 58
SINCRONIZAÇÃO DE RECURSOS COM TRANSAÇÕES 63
CONTROLE DECLARATIVO DE TRANSAÇÕES 64
CONTROLE PROGRAMÁTICO DE TRANSAÇÕES 72
conclusão 76
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 13/84
LISTA DE ILUSTRAÇÕES
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 14/84
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 15/84
LISTA DE TABELAS
Ilustração 1: Módulos do Spring 15
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 16/84
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 17/84
LISTA DE SIGLAS
EJB – Enterprise Java Beans
DAO – Database Access Object
DI – Dependency Injection
AOP – Aspect-Oriented Programming
ORM – Object-Relacional Mapping
JEE – Java Enterprise Edition
I18n – Internacionalização
JSF – Java Server Faces
MVC – Model/View/Controller
IoC – Inversion of Control
TI – Tecnologia da Informação
JNDI - (Java Naming and Directory Interface)
SGBD – Sistema Gerenciador de Banco de Dados
Java Transaction API (JTA)
Container-Managed Transations (CMT)
(Logical Unit of Work, LUW)
ACID – Atomiciade, Consistencia, Isolamento e Durabilidade
Java Transaction Services (JTS)
Java Transaction API (JTA)
(Single Unit of Work, SUW)
SQL – Standard Query Language
JMS – Java Messaging Service
MDB (Message-Driven Beans)
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 18/84
introdução
Objetivo
Este trabalho acadêmico tem como principal objetivo dar ao leitor uma visão geral sobre o Spring
Framework e sobre as Transações em Java. Por fim, visa demonstrar maneiras de implementar o controle de
transações com esta plataforma.
Metodologia
A principal metodologia utilizada na realização deste trabalho é a pesquisa em artigos e livros, pois são a fonte
mais completa de informação relacionada ao assunto que está sendo discutido.
Estrutura do Trabalho
A estrutura do trabalho se dará conforme segue:
Capitulo 1 – Visão Geral do Spring Framework
Capitulo 2 – Transações Java
Capitulo 3 – Controle de Transações com Spring Framework
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 19/84
visão geral do Spring Framework
Spring Framework é uma plataforma de código fonte aberto, criado por Rod Johnson.
“Foi criado para diminuir a complexidade da criação de aplicações corporativas. O Spring torna possívelo uso de simples JavaBeans para atingir objetivos que antes eram possíveis com o uso dos EnterpriseJavaBeans. De qualquer maneira, a usabilidade do Spring não está limitada à camada do servidor.Qualquer aplicação Java pode se beneficiar do Spring em termos de simplicidade, testabilidade e baixoacoplamento”.(WALLS; BREIDENBACH, 2007, p.5)
Segundo WALLS; BREIDENBACH (2007), por ter muitas funcionalidades, o Spring, quando analisado mais
detalhadamente, se mostra um container e um framework leve, com suporte à Orientação a Aspectos e Injeção de
dependência.
Leve: Spring é leve em tanto termos de tamanho físico quanto em termos de custo de processamento. Seu
tamanho físico é distribuído em um único arquivo JAR que pode ocupar até 2.5 MB. O custo de
processamento requerido pelo Spring é negligenciável. Além disso, a plataforma é não-intrusiva: objetos em
uma aplicação que a utiliza frequentemente não tem dependências de classes específicas do framework.
Injeção de Dependência: Spring promove o baixo acoplamento através de uma técnica conhecida como
Injeção de Dependência (Dependency Injection ou DI). Quando a Injeção de Dependência é aplicada, são
passivamente injetadas as dependências nos objetos ao invés dos próprios objetos criarem as dependências ou
buscarem a dependência por si próprios. Pode-se imaginar a Injeção de Dependência como um lookup JNDI
reverso – ao invés do objeto buscar sua dependência no container através do nome JNDI, o próprio
container injeta as dependências em tempo de instanciação sem ao menos ser requisitado para tal.
Orientado a Aspecto: O Spring tem um rico suporte para programação orientada a aspectos, o que
possibilita um desenvolvimento coeso, separando assim a lógica de negócios da aplicação dos serviços do
sistema (como auditoria ou mesmo o controle de transação). Os objetos de negócio apenas executam as regras
de negócio para as quais foram designados, não tendo assim a responsabilidade de realizar nenhuma tarefa
além desta.
Container: Spring é um container, pois contém e gerencia o ciclo de vida e a configuração dos objetos da
aplicação. Por meio desta plataforma, pode-se declarar a maneira a qual cada um dos objetos deverá ser
criado, configurado e até associado a outros objetos.
Plataforma: Ele torna possível compor e configurar aplicações complexas a partir de componentes simples.
Nele, os objetos da aplicação são intanciados declarativamente, geralmente por meio de arquivo XML.
Fornece também uma gama de funcionalidades de infra-estrutura (gerenciamento de transações, framework de
integração com persistência).
Pode-se perceber que o Spring tem um forte apelo para o desenvolvimento de aplicações fracamente
acopladas. Porém, esta não é a sua única funcionalidade. Ele é composto alguns módulos que o transformam em uma
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 20/84
plataforma repleta de funcionalidades que visam facilitar a construção de aplicações corporativas.
MODULOS DO SPRING FRAMEWORK
Para JOHNSOL et AL (2009), o Spring pode ser dividido em seis principais módulos, os quais agrupam
todas as suas funcionalidades, como mostra a ilustração 1.
Apesar dele ser composto por todos estes módulos,o único módulo mandatório para que a plataforma seja
executada é o Spring Core. Os demais módulos podem ser adicionados ou removidos de acordo com a necessidade
de desenvolvimento de cada aplicação.
Ilustração 1: Módulos do Spring
Fonte: JOHNSON et all (2009)
1.1.1MODULO CORE
Segundo JOHNSON et AL (2009), o modulo Core é o principal pacote a plataforma. Verifica-se por meio
da ilustração 1 que todos os outros módulos utilizam-se deste para que possam implementar suas funcionalidades. O
conceito básico utilizado por este módulo é a BeanFactory, uma implementação sofisticada do padrão de projetos
Factory, que permite desacoplar a injeção de dependência da lógica de programação.
1.1.2MODULO JEE
Para JOHNSON et AL (2009), o módulo JEE (ou também conhecido como Contexto) é baseado no modulo
Core. Enquanto aquele módulo faz do Spring um container, o módulo JEE faz do Spring uma plataforma. Este módulo
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 21/84
dá suporte a serviços como a internacionalização (I18N), acesso a JNDI, integração com EJB, propagação de
eventos, carga de recursos, criação transparente de contextos (como por exemplo o Container de Servlets), entre
outros.
1.1.3MÓDULO DAO
Segundo WALLS; BREIDENBACH (2007), este módulo é a camada de abstração para os códigos comuns
usados quando temos que controlar a conexão via JDBC. Ele abstrai os trechos de códigos repetidos ao tentar
controlar a conexão, manuseando-a de maneira adequada e, assim, tornando o código mais limpo.
1.1.4MÓDULO ORM
WALLS; BREIDENBACH (2007) nos ensina que este módulo provém uma camada de integração entre o
Spring Framework e os as plataformas mais populares de mapeamento Objeto-Relacional (Hibernate, JPA, JDO,
iBatis). Em conjunto com o módulo AOP, fornecem o controle declarativo de transações.
1.1.5MÓDULO AOP
Ainda segundo WALLS; BREIDENBACH (2007), o módulo AOP (Aspect-Oriented Programming)
oferece suporte completo à programação orientada a aspectos.
Este módulo é a base para o desenvolvimento de aspectos em aplicações Spring. Assim como DI, AOP dá
suporte ao baixo acoplamento de objetos. Com AOP, as preocupações não funcionais (controle de transações e
segurança, por exemplo) são desacopladas dos objetos aos quais são aplicadas.
1.1.6MODULO WEB
Para WALLS; BREIDENBACH (2007) , o paradigma Model/View/Controller (MVC) é uma abordagem
comummente aceitada para construir aplicações web em que a camada de apresentação é separada da camada de
lógica da aplicação
O módulo Web dá suporte para o MVC e oferece integração com vários frameworks existentes no mercado
(Struts, JSF, Webwork), como também oferece a sua própria solução, em termos de plataforma web, que é o Spring
MVC.
INJEÇÃO DE DEPENDÊNCIA
Como já dito anteriormente, o Spring Framework tem diversas funcionalidades para a construção de
aplicações Java. Porém a injeção de dependência é uma das funcionalidades mais importantes que o framework
oferece.
1.
1.1.7ENTENDENDO O CONCEITO
Para MACHACEK et AL (2008), injeção de dependência é um padrão de desenvolvimento de software
que tem como objetivo manter o fraco acoplamento entre os componentes existentes na aplicação. Para tal, utiliza-se
da abstração das classes por meio de de interfaces.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 22/84
Programando por meio de de interfaces, o Spring recupera, com seus arquivos de configuração a
implementação correta que deverá ser atribuída a cada classe, tirando da classe de serviços a responsabilidade de
obter suas dependências.
No contexto da injeção de dependência, o Spring atua mais como um container do que como um
framework – provendo instâncias das classes da aplicação com todas as dependências que elas precisam – de uma
maneira muito pouco intrusiva.
O uso da injeção de dependência traz vários benefícios, tais como:
Diminuir o Acoplamento: Uma grande vantagem obtida através da injeção de dependêcia é a possibilidade
de de reduzir a quantidade de código escrita para se agregar diferentes componentes da aplicação em uma
determinada classe. É apenas necessária uma instancia da classe em questão. As outras dependências são
injetadas pelo container, sem a interação do programador.
Externalizar dependências: A configuração das dependências não está dentro do código fonte, o que permite
que as dependências sejam alteradas, caso haja necessidade, sem a necessidade de recompilar a aplicação.
Centralizar o gerenciamento de dependências: Todas as informações referentes às dependências se
encontram em um único arquivo de configuração, o que aumenta a manutenibilidade do sistema.
Aumenta a testabilidade: Muitas vezes quando precisa-se testar uma classe de negócios na aplicação, um
problema comum aparece: a classe em questão, na maiora das vezes, não realiza todo o trabalho sozinha. Pode
estar associada a um DAO ou mesmo a outra classe de serviço. Por se trabalhar com a injeção de
dependência, torna-se fácil a substituição de dependências. Isto facilita a criação de novas implementações das
classes de serviço, ou mesmo DAO, para que atendam o propósito daquele teste, e a atribuição destas novas
implementações nas classes que serão testadas.
Forçar um bom design das aplicações: Uma aplicação tipicamente orientada a injeção é desenhada de tal
modo que seus componentes são todos definidos como interface e suas implementações são criadas e ligadas
através da injeção de dependências.
1.1.8INJETANDO DEPENDENCIAS
Conforme nos ensina WALLS; BREIDENBACH (2007), em uma simples aplicação com duas ou mais
classes, sempre que existe a necessidade de uma determinada classe de acessar os métodos (serviços) de outra
classe, a primeira solução encontrada é a instanciação ou a pesquisa pelo serviço por meio de de seu nome JNDI
(Java Naming and Directory Interface), como mostra o código abaixo:
package br.com.fatec.tcc;
public class ServiceOne {
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 23/84
public void importantService(){
//código importante com lógica de negócio
ServiceTwo st = new ServiceTwo();
st.importantService();
//mais lógica de negócio
}
}
package br.com.fatec.tcc;
public class ServiceTwo {
public void importantService(){
System.out.println("HelloWorld");
}
}
Pode-se ver que o objeto ServiceOne é o responsável por obter a dependência referente ao objeto
ServiceTwo, por meio de de uma instanciação simples (poderia ser por um lookup também; da mesma maneira, a
responsabilidade continuaria sobre a classe ServiceOne).
No contexto da Injeção de Dependência, ocorre uma inversão da responsabilidade (por este motivo DI é
conhecida também como Inversion of Control ou IoC). Quem é o responsavel por injetar as dependências é o
próprio container do Spring.
Antes de implementar a DI, a partir deste ponto, pode-se assumir que as classes acima citadas estão agora
implementando a interface br.com.fatec.tcc.Service , que é implementada da seguinte maneira:
package br.com.fatec.tcc;
public interface Service {
public void importantService();
}
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 24/84
Para WALLS; BREIDENBACH (2007), uma técnica comum para reduzir o acoplamento é esconder os
detalhes da implementação atrás de interfaces, para que assim, a implementação possa ser modificada ser afetar a
classe cliente do serviço. Desta maneira, as classe acima agora ficam desta maneira:
public class ServiceOne implements Service{
public void importantService(){
//código importante com lógica de negócio
Service st = new ServiceTwo();
st.importantService();
//mais lógica de negócio
}
}
public class ServiceTwo implements Service{
public void importantService(){
System.out.println("HelloWorld");
}
}
1.1.8.1INJEÇÃO POR CONSTUTOR
Segundo JOHNSON et AL (2009), a injeção de dependências através do construtor é realizada por meio da
invocação do construtor com um número qualquer de argumentos, cada um deles representando uma dependência.
A implementação da classe ServiceOne, afim de que atenda os requisitos para ter as suas dependências
injetadas através de seu construtor deverá ficar conforme o trecho de código abaixo:
package br.com.fatec.tcc;
public class ServiceOne implements Service{
ServiceTwo st;
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 25/84
public ServiceOne(ServiceTwo st){
this.st = st;
}
//restantes métodos da classe
}
No arquivo applicationContext.xml (arquivo de configuração do Spring), estarão as seguintes configurações:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="so" class="br.com.fatec.tcc.ServiceOne">
<constructor-arg>
<bean class="br.com.fatec.tcc.ServiceTwo" />
</constructor-arg>
</bean>
</beans>
Para MACHACEK et AL (2008), para o Spring, o termo bean se refere a qualquer componente que seja
gerenciado pelo container. Portanto, a tag <beans> delimita a área de definição dos componentes que serão
gerenciados pelo container. Já a tag <bean> serve para definir os componentes própriamente ditos, como
componentes de negócio, data-sources, entre outros.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 26/84
No exemplo acima, definiu-se o componente ServiceOne com id de “so” e seu tipo (a propriedade class
sempre deverá ser preenchida com o nome completo da classe). Com a tag <constructor-arg>, pode-se definir os
argumentos que serão passados como parâmetro para o construtor. Neste caso, em específico, não ocorrerá
problema de ambigüidade, pois existe apenas um argumento. Porém, se houvesse mais de um argumento, poderia-se
utilizar de outros artifícios para eliminar este problema, conforme trecho de código abaixo. Por padrão, o Spring
utiliza-se do type matching.
public class ServiceOne implements Service{
ServiceTwo st;
public ServiceOne(int arg1, String arg2){
this.st = st;
}
//restantes métodos da classe
}
O construtor acima recebe dois argumentos (um do tipo primitivo int e um do tipo String). Pode-se contornar
esta situação de duas maneiras: pode-se definir o tipo do argumento no arquivo de configuração ou, também, definir o
índice do argumento do construtor.
1.1.8.1.1IDENTIFICAÇÃO DE ARGUMENTO POR TIPO
Pode-se identificar os argumentos do construtor apenas especificando seus tipos, como mostra o exemplo
abaixo:
<bean id="so" class="br.com.fatec.tcc.ServiceOne">
<constructor-arg>
<bean type="java.lang.String" value="666" />
<bean type="int" value="13" />
</constructor-arg>
</bean>
Percebe-se que não há a necessidade de seguir, na definição dos argumentos, a ordem em que aparecem
definidos na classe. O Spring trata de fazer a correspondência de tipos automaticamente.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 27/84
1.1.8.1.2IDENTIFICAÇÃO DE ARGUMENTO POR INDICE
Desta maneira, identifica-se os argumentos definidos no construtor da classe por meio de seu índice, ou seja, a
ordem na qual eles foram definidos no construtor. O índice inicia em zero.
<bean id="so" class="br.com.fatec.tcc.ServiceOne">
<constructor-arg>
<bean index="1" value="666" />
<bean index="0" value="13" />
</constructor-arg>
</bean>
Desta maneira, resolve-se o problema de um construtor que tem diversos argumentos do mesmo tipo.
1.1.8.2INJEÇÃO POR SETTERS
Segundo MACHACEK et AL (2008), quando trata-se da injeção de dependência por meio dos métodos
setter, assume-se que o próprio container irá instanciar o objeto e invocará seus métodos setter para injetar as
dependências especificadas no arquivo de configuração do Spring.
A classe ServiceOne, neste novo modelo de injeção de dependência seria codificada da seguinte maneira:
public class ServiceOne implements Service{
Service st;
//restantes métodos da classe
public void setSt(Service st) {
this.st = st;
}
}
Neste momento, precisa-se definir as dependências do objeto (neste caso, injetaremos uma instância da
classe ServiceTwo) no arquivo de configuração, como segue:
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 28/84
<bean id="st" class="br.com.fatec.tcc.ServiceTwo" />
<bean id="so" class="br.com.fatec.tcc.ServiceOne">
<property name="st" ref="st">
</bean>
Neste exemplo, são definidos dois serviços (ServiceOne e ServiceTwo) como componentes que serão
gerenciados pelo container do Spring. No bean referente à classe ServiceOne, definimos uma de suas propriedades
por meio da tag <property>. Utiliza-se dois atributos desta tag, que são os atributos “name” e “ref”. O atributo
“name” refere-se ao nome com o qual a propriedade foi definida na classe em que se está injetando a dependência.
Já a tag “ref” é uma referência à um outro bean que for definido no arquivo de configurações. Seu valor é o “id” do
bean que fora definido outrora.
A única restrição que necessita ser seguida é que a convenção do JavaBean. O Spring busca pelos métodos
setters de acordo com essa convenção.
Para JOHNSON et AL (2009), torna-se evidente que códigos ficam mais limpos após o principio da injeção
de dependências ser aplicado, e atingir um alto grau de desacoplamento é mais fácil quando os objetos não fazem
lookup por suas dependências e sim, elas são apenas dadas a eles.
SUPORTE A PROGRAMAÇÃO ORIENTADA A ASPECTOS
2.
1.1.9ORIENTAÇÃO A ASPECTOS
Segundo WALLS; BREIDENBACH (2007), a programação orientada a aspectos é geralmente definida
como uma técnica de programação que promove a separação das preocupações não funcionais dentro de uma
aplicação. Estas preocupações não funcionais são também conhecidas como interesses transversais. Um bom
exemplo de interesse transversal de aplicações corporativas pode ser a geração de logs, ou mesmo o gerenciamento
de transações.
Pode-se separar todas as atividades relativas à geração de log, por exemplo, em um componente separado
do sistema. Porém, mesmo assim, continua existindo a necessidade de invocação destas funcionalidades por todas as
partes do código que necessitem deste serviço. Por exemplo, pode haver a necessidade de logar o desempenho de
uma busca SQL. Para isto, deveria-se invocar um método do componente de log antes do início da execução da
instrução SQL e também, logo após a sua execução, para que o sistema possa informar qual foi o tempo de execução
desta. Pensando desta forma, pode-se calcular o número de vezes que este código, responsável por fazer o log do
desempenho, será repetido em toda a aplicação. Usando a Orientação a Aspectos, pode-se simplesmente especificar
que, em todos os métodos que realizem uma busca, inserção, deleção ou atualização no banco de dados, seja
realizada a chamada do método de log antes e depois da execução.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 29/84
Além de ter muito código replicado em nossa aplicação, acaba-se diminuindo a coesão do código da
aplicação, pois cada componente, além da sua responsabilidade de negócios, tem atribuído a si a responsabilidade de,
por exemplo, gerar logs, gerenciar a transação, gerenciar a segurança, entre outras.
Para JOHNSON et AL (2009), a Orientação a Aspectos complementa a Orientação a Objetos provendo
uma maneira diferente de pensar na estrutura do programa. A modularização chave da orientação a objetos é a classe,
enquanto na orientação a aspectos, temos o aspecto como modularização básica.
MACHACEK et AL (2008) nos dá uma breve explicação dos principais conceitos da Orientação à
Aspectos.
Joinpoint: Joinpoints são pontos bem definidos dentro de uma aplicação. Basicamente este ponto é onde o
aspecto será aplicado. Pode ser a invocação de um método, a instanciação de um objeto, a inicialização de
uma classe. Este é o ponto principal da orientação a aspectos.
Advice: É o código executado a partir de um joinpoint. Existem diferentes tipos de advice, incluindo o before
advice, que é executado antes do joinpoint, e o after advice, que é executado após.
Ilustração 2: Um advice sendo introduzido entre vários joinpoints durante a execução de um programa.
Fonte: WALLS; BREIDENBACH (2007)
Pointcuts: Um pointcut é um conjunto de joinpoints. Um pointcut típico é um conjunto de joinpoints de
uma classe, porém, pode ser composto de vários joinpoints de várias classes. Isto ajuda a ganhar controle
sobre os advices que serão executados.
Aspects: Aspecto é uma combinação de advices e pointcuts. Esta combinação resulta na lógica que deve ser
incluída na aplicação e onde ela deve ser executada.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 30/84
Weaving: Este é o processo de criação de objetos com os aspectos inseridos dentro de seu código. Neste
caso, o framework recupera o código dos aspectos e o código dos objetos que devem ser afetado por tal
aspecto, mescla e cria uma classe só. Isto pode acontecer tanto em tempo de compilação quanto em tempo de
execução. O Spring pode realizar este processo tanto em tempo de compilação quanto em tempo de
execução.
Target: É o objeto que vai ser afetado por um ou mais aspectos. Também referenciado como advised object.
Introduction: Introdução é o processo pelo qual pode-se modificar a estrutura de um objeto, introduzindo
para isto, métodos e atributos em tempo de execução. É possivel utilizar-se disto para fazer com que um objeto
implemente uma determinada interface sem que a classe deste objeto implemente isto explicitamente.
1.1.10TIPOS DE AOP
1.1.10.1AOP Estática
Segundo MACHACEK et AL (2008), entende-se que muitas das primeiras implementações da AOP foram
estáticas. Na AOP estática, o processo de tecelagem (weaving) é uma nova fase no processo de construir a
aplicação. Ou seja, o processo de weaving é atingido por meio da modificação do bytecode da aplicação,
modificando e herdando o código da maneira que for necessária em tempo de compilação. Esta modalidade de AOP
é mais performática, porém, qualquer tipo de modificação que seja feita nos aspectos necessitará de uma total
recompilação do código.
1.1.10.2AOP Dinâmica
Ainda segundo MACHACEK et AL (2008), as implementações dinâmicas de AOP se diferenciam das
implementações estáticas pelo fato de o processo de weaving ser realizado em tempo de execução. A principal
desvantagem desta abordagem é não ser tão performática quanto a AOP estática. Por outro lado, o maior benefício é
a facilidade com que se podem modificar os códigos dos aspectos sem ter que recompilar todo o código principal. O
Spring AOP é implementado desta maneira.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 31/84
Transações Java
O QUE É UMA TRANSAÇÃO?
Sabe-se que, de uma maneira simples, transação é uma unidade única, composta por um ou mais processos.
Estes processos tem uma relação lógica entre eles e devem ser considerados como um só. Precisa-se tratá-los desta
maneira pelo fato de que a execução de cada um destes processos necessita da conclusão bem sucedida do processo
anterior. (SARANG, P.G. et AL, 2001).
QUAL A NECESSIDADE DE UMA TRANSAÇÃO
Observou-se que as transações oferecem um método estruturado para o controle da execução de todos os
processos de uma transação, assegurando o seu sucesso ou lidando com a sua falha.
Há muitas razões para o uso das transações. Um deles se dá quando necessitamos agrupar vários passos de
um processo em uma única unidade de processo. Esta unidade deve ser completada com sucesso ou não completada.
Aplicações concorrentes, que suportam multiplos usuários ao mesmo tempo tem problemas inerentes que
precisam ser endereçados. O acesso aos dados deve ser gerenciado e coordenado. Caso contrário, corre-se o risco
da corrupção dos dados. As transações provém um mecanismo no qual as aplicações possam estar cientes de tais
erros e possam lidar com isto.
Em suma, transações ajudam à aliviar a complexidade de coordenar o acesso aos dados e recursos dentre
vários clientes(SARANG, P.G. et AL, 2001).
PROPRIEDADES DE UMA TRANSAÇÃO
Endende-se, pelos ensinamentos de SARANG, P.G. et AL (2001) e RICHARDS (2006), que cada
transação deve mostrar quatro características principais: Atomicidade, Consistência, Isolamento e Durabilidade. Estas
propriedades são representadas pelo acrônimo ACID, descrito à seguir:
3.
4.
5.
1.1.11Atomicidade
Esta propriedade é referenciada em algumas oportunidades como Unidade Lógica de Trabalho (Logical Unit
of Work, LUW) ou Unidade Única de Trabalho (Single Unit of Work, SUW).
A atomicidade implica que uma transação, por mais que tenha diversos processos inerentes à ela, estes
deverão ser tratados como um só. A execução de cada um dos processos conta com a conclusão bem-sucedida do
anterior; caso haja alguma falha, nenhum dos outros processos executará.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 32/84
A atomicidade nos ajuda a colocar limites lógicos dentro de um processo. Por meio dela, conseguimos indicar
o início e o fim destes limites. Desta maneira, se todos os passos tem processamento bem-sucedido, as modificações
são gravadas permanentemente. Caso haja alguma falha dentro destes limites, as alterações realizadas pelos processos
já executados até o momento serão desfeitas.
1.1.12Consistencia
Consistência garante que a transação deixará os dados consistentes após a sua conclusão. Costuma-se dizer
que os dados estão consistentes quanto eles aderem às regras e restrições do banco de dados. Se o sistema está com
os dados consistentes antes do início da transação, deverão permanecer desta maneira depois do seu fim,
independentemente da transação ser finalizada com sucesso ou de haver algum tipo de falha durante o processamento.
A consistência não permite que seja violada alguma restrição de chave estrangeira, por exemplo, mesmo que
programaticamente o processo fosse corrigir este estado em uma parte posterior da transação.
1.1.13Isolamento
A propriedade Isolamento é uma referência à maneira em que transações distintas interagem entre si. Esta é
uma das características mais poderosas das transações. Ela garante que os dados acessados por uma transação não
serão afetados por nenhuma mudança realizada por outras transações até que ela se complete.
Isso efetivamente permite com que as transações executem como se fossem as únicas do sistema. Outras
operações no banco de dados serão apenas permitidas caso não afetem nenhum dado que uma transação esteja
manuseando naquele determinado momento. Esta propriedade é vital para o suporte ao acesso concorrente aos
dados.
1.1.14Durabilidade
Esta propriedade especifica que quando uma transação está finalizada, qualquer mudança feita aos dados
devem ser gravados em um dispositivo de armazenamento permanente.
Os logs de transação são uma das ferramentas para implementar a durabilidade. Eles guardam dados que um
recurso, como um banco de dados, pode usar para re-aplicar transações que podem ter sido perdidas por resultado
de uma falha, ou desfazer algumas transações devico a algum tipo de erro. Basicamente, um log de transações rastreia
todas as operações de manipulação de dados que ocorreu no sistema para que, no caso de corrupção de dados, por
exemplo, o sistema possa voltar ao estado conhecido (incorrompido).
PROCESSAMENTO TRANSACIONAL
Segundo SARANG, P.G. et AL (2001) , as transações geralmente realizam o seguinte fluxo:
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 33/84
Ilustração 3: Fluxo geral de uma trasançao.
Fonte: SARANG, P.G. et AL (2001)
SARANG, P.G. et AL (2001) também diz que no que tange o código, as transações devem seguir o padrão
abaixo:
Ilustração 4:Código em linguagem natural representando uma transação.
Fonte: SARANG, P.G. et AL (2001)
Primeiramente, é indicado o início da transação.O processo de identificação de onde fica o início e o fim da
transação (também chamados de limites transacionais) é chamado demarcação.Todo o código que deve ser
executado é colocado dentro da transação. Ao final dela, existe uma verificação, que consiste em identificar se todos
os processos foram realizados com sucesso. Caso tenham sido realizados com sucesso, os dados são gravados
permanentemente. Caso contrário, todas as alterações deverão ser desfeitas. Após esta fase, a transação se encerra.
MODELOS DE TRANSAÇÃO
Segundo RICHARDS (2006), há três tipos de transação em Java, que são Modelo de Transação Local,
Modelo de Transação Programático e Modelo de Transação Declarativa.
6.
7.
1.1.15Modelo de Transação Local
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 34/84
Segundo RICHARDS (2006), este modelo recebe este nome pois não é exatamente o framework que
controla a transação, mas sim, o fornecedor dos dados aos quais a aplicação está conectada. Por exemplo, quando a
aplicação está conectada à um banco de dados, o gerenciador de recursos é implementado por meio do driver do
banco de dados e do proprio Sistema de Gerenciamento de Banco de Dados (SGBD). Neste modelo, o
desenvolvedor gerencia conexões, não transações.
O código abaixo ilustra este modelo de transações, utilizando JDBC:
public void atualizaRegistro() throws Exception{
DataSource dataSource =
(DataSource)new InitialContext().lookup("jdbc/MeuDataSource");
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
String sql_1 = "UPDATE tabela_exemplo SET campo_1 = 'Olá Mundo'";
String sql_2 = "UPDATE tabela_exemplo SET campo_1 = 'Tchau Mundo'";
try {
stmt.executeUpdate(sql_1);
stmt.executeUpdate(sql_2);
conn.commit();
} catch (Exception e) {
conn.rollback();
throw e;
}finally{
stmt.close();
conn.close();
}
}
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 35/84
1.1.15.1AutoCommit e Gerenciamento de Conexões
Veja que no código acima foi utilizado o método Connection.setAutoCommit(false) em conjunto com os
métodos Connection.commit() e Connection.rollback(). Entende-se através dos ensinamentos de RICHARDS
(2006), que o método setAutoCommit() é um método importante no gerenciamento de conexões pelo usuário, pois
ele diz se o SGBD deve ou não realizar o commit automático das informações logo após a execução das instruções
SQL. Por padrão, a flag redefinida por este método é verdadeiro. Caso seja alterada para falso, a conexão será
mantida ativa e não executará nem commit e nem rollback nas alterações a menos que explicitamente sejam
executados os métodos commit() e rollback(), respectivamente.
No código abaixo, foi adicionado uma segunda instrução SQL de atualização e removidos as seguintes
invocações: Connection.setAutoCommit(false), Connection.commit() e Connection.rollback(). Desta maneira, apesar
de o código compilar e executar, não mantém mais as propriedades ACID de uma transação.
public void atualizaRegistro() throws Exception{
DataSource dataSource =
(DataSource)new InitialContext().lookup("jdbc/MeuDataSource");
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
String sql_1 = "UPDATE tabela_exemplo SET campo_1 = 'Olá Mundo'";
String sql_2 = "UPDATE tabela_exemplo SET campo_1 = 'Tchau Mundo'";
try {
stmt.executeUpdate(sql_1);
stmt.executeUpdate(sql_2);
} catch (Exception e) {
throw e;
}finally{
stmt.close();
conn.close();
}
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 36/84
}
Primeiramente, o código acima não mantém as propriedades pelo fato de não estar sendo tratado como uma
única unidade de trabalho, ou seja, pelo fato da flag de auto commit estar como verdadeiro, a gravação final no banco
de dados será executada logo após a execução de cada um dos comandos de atualização. Em segundo lugar, as duas
atualizações, como parte de uma unidade lógica de trabalho não estão isoladas de outros processamentos que possam
estar acessando a mesma tabela ou até as mesmas linhas da tabela em questão.
Para tornar o código propício, de um ponto de vista transacional e da perspectiva LUW, devemos definir a
flag de auto commit para false e transferir os comandos commit e rollback para o nosso código. Desta maneira,
poderemos agrupar as instruções SQL em uma única unidade de trabalho dentro de uma transação atômica.
public void atualizaRegistro() throws Exception{
DataSource dataSource =
(DataSource)new InitialContext().lookup("jdbc/MeuDataSource");
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
String sql_1 = "UPDATE tabela_exemplo SET campo_1 = 'Olá Mundo'";
String sql_2 = "UPDATE tabela_exemplo SET campo_1 = 'Tchau Mundo'";
try {
stmt.executeUpdate(sql_1);
stmt.executeUpdate(sql_2);
conn.commit();
} catch (Exception e) {
conn.rollback();
throw e;
}finally{
stmt.close();
conn.close();
}
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 37/84
}
1.1.15.2Considerações e Limitações do Modelo de Transação Local
Segundo RICHARDS (2006), este modelo trabalha de maneira satisfatória para simples atualizações na base
de dados e aplicações de pequeno porte. Há algumas limitações neste modelo que podem trazer sérios problemas
para a arquitetura desta aplicação.
O primeiro problema com o Modelo de Transações Locais é que ele é muito propício à erros no que diz
respeito à logica de controle de conexões. O desenvolvedor tem que atentar muito para a flag de auto commit,
particularmente quando há várias instruções de manipulação de dados em um determinado método. Também, o
desenvolvedor deve ficar atento aos métodos que são invocados e também se eles gerenciam conexões. A menos que
estejamos falando de um sistema pequeno e com poucas tabelas, não há uma maneira eficaz de garantir as
propriedades ACID da transação.
Outro problema com este modelo é que transações locais não podem existir em sistemas com acessos
concorrentes à bases distribuídas. Quando se coordena multiplos recursos, como um banco de dados e uma fila JMS,
não pode-se usar o Modelo de Transações Locais e ainda manter as propriedades ACID de uma transação. Dadas
estas restrições e limitações, este modelo deve ser utilizado para sistemas pequenos, não complexos e com poucas
tabelas.
1.1.16Modelo de Transação Programático
RICHARDS (2006) nos ensina que este modelo se aproveita do poder da Java Transaction API (JTA). Com
este modelo, o desenvolvedor escreve código que gerencia transações e não conexões. Usando a interface
javax.transaction.UserTransaction o desenvolvedor codifica o método begin() para iniciar a transação e o commit() ou
rollback() para terminá-la. O trecho de código abaixo exemplifica este modelo usando EJB:
public void atualizaRegistro(DadosExemplo dados) throws Exception {
UserTransaction txn = sessionCtx.getUserTransaction();
txn.begin();
try {
ExemploDAO dao = new ExemploDAO();
dao.atualizaDadosExemplo(dados);
txn.commit();
} catch (Exception e) {
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 38/84
log.fatal(e);
txn.rollback();
throw e;
}
}
No exemplo acima, o contexto da transação é propagado para o objeto ExemploDAO e, diferentemente do
Modelo de Transações Locais, o objeto ExemploDAO não tem que gerenciar conexões ou transações.
No Modelo de Transações Programáticas, o desenvolvedor é responsável por iniciar e terminar uma
transação. O método begin() é utilizado para iniciar a transação e os métodos commit() e rollback() são utilizados
para terminá-la. Usando EJB, isto é feito por meio da interface UserTransaction. Usando Spring Framework, é feito
por meio da interface TransactionTemplate ou pela interface PlataformTransactionManager, localizados no pacote
org.springframework.transaction.
1.1.16.1Armadilhas do Modelo de Transações Programáticas
Segundo RICHARDS (2006), quando se utiliza este modelo para o controle das transações, os
desenvolvedores devem dar uma atenção especial ao tratamento de exceções. Considere o código abaixo, no qual se
ignora às exceções de tempo de execução:
public void atualizaRegistro(DadosExemplo dados) throws Exception {
UserTransaction txn = sessionCtx.getUserTransaction();
txn.begin();
try {
ExemploDAO dao = new ExemploDAO();
dao.atualizaDadosExemplo(dados);
txn.commit();
} catch (ApplicationException e) {
log.fatal(e);
txn.rollback();
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 39/84
throw e;
}
}
Caso aconteça algum tipo de exceção em tempo de execução (por ex. ClassCastException,
NullPointerException), o container trataria estas exceções e desfaria o que foi realizado na transação (rollback).
Porém, caso não houvesse tratamento para as exceções da aplicação, como no trecho abaixo, a responsabilidade de
tratar a exceção seria toda do método que previamente invocou o método atualizaRegistro().
public void atualizaRegistro(DadosExemplo dados) throws Exception {
UserTransaction txn = sessionCtx.getUserTransaction();
txn.begin();
ExemploDAO dao = new ExemploDAO();
dao.atualizaDadosExemplo(dados);
txn.commit();
}
Caso o sistema tenha alguma exceção da aplicação no trecho de código mostrado acima, a execução
retornaria a seguinte exceção de tempo de execução (Runtime Exception):
java.lang.Exception:[EJB:011063] Stateless session beans with bean-managed transactions must
commit or rollback their transaction before completing a business method.
Usar o Modelo Programático de Controle de Transações significa que os desenvolvedores são os
responsáveis por controlar a transação. Portanto, um método que inicia uma transação é obrigado a terminá-la. Isto
pode ser mais difícil do que parece, particularmente para sistemas complexos e grandes com tratamentos complexos
de exceção.
1.1.17Modelo de Transação Declarativa
Segundo RICHARDS (2006), este modelo também é conhecido como Container-Managed Transations
(CMT). Nele, o framework ou o container que gerencia o inicio e o fim das transações. Os desenvolvedores apenas
se preocupam em mostrar ao framework quando reverter a transação por meio de exceções da aplicação,
configuradas em descritores XML particulares à cada framework (por exemplo, ejb-jar.xml para o EJB ou
ApplicationContext.xml para o Spring Frameework).
1.1.17.1Atributos Transacionais
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 40/84
Segundo SARANG, P.G. et AL (2001), com o Modelo de Transação declarativa, pode-se especificar para o
container quais métodos estarão sujeitos ao controle transacional. Além disso, é possível especificar certas
propriedades comportamentais que controlam quando e como uma transação será criada, dependendo da
necessidade do componente em relação ao contexto transacional. Contexto transacional se refere à um
relacionamento entre as operações transacionais conduzidas em um determinado grupo de recursos e os clientes
acessando estes recursos. O contexto transacional incorpora o seu início, na requisição do cliente, e seu fim. Qualquer
operação executada em um recurso dentro de uma transação é considerada dentro do contexto transacional e estará
sujeito às suas regras.
Abaixo estão os seis atributos de transação suportaos pelo Spring Framework e pelo EJB:
Required
Mandatory
RequiresNew
Supports
NotSupported
Never
Segundo RICHARDS (2006), o Spring Framework tem um atributo adicional: PROPAGATION_NESTED.
Este atributo diz ao Spring para aninhar a transação atual e utilizar o atributo REQUIRED. Para tal, a implementação
do serviço subjacente de transações deve suportar transações aninhadas. Embora todos os atributos acima possam
ser definidos à nivel de classe, eles geralmente são utilizados para alterar os atributos transacionais de um método.
Quando um atributo transacional é utilizado em nivel de classe, todos os métodos daquela classe terão o mesmo
comportamento definido por ele. Porém, este comportamento padrão pode ser sobescrito por meio da utilização
destes atributos em nivel de métodos.
1.1.17.1.1REQUIRED
Segundo SARANG, P.G. et AL (2001), o atributo transacional REQUIRED (no Spring,
PROPAGATION_REQUIRED) indica que o método especificado deve sempre ser executado dentro do contexto
de uma transação. Caso o método seja invocado dentro do contexto de uma transação existente, esta transação será
utilizada ou propagada. Caso não exista um contexto transacional no momento da invocação, o container criará um. A
nova transação iniciará quando o método iniciar e terminará quando a execução do método terminar. Caso seja
necessário um rollback, o container desfará o que foi realizado durante esta transação e lançará uma
RollbackException, permitindo assim que o método que invocou o método possa tratar esta falha.
Ainda segundo SARANG, P.G. et AL (2001), este atributo deve ser utilizado sempre que o método for
modificar algum tipo de dado, para certificar que este sempre estará envolvido por uma transação.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 41/84
A figura 5 ilustra o comportamento da transação com este atributo transacional:
Ilustração 5:Mecanismo de controle de transações declarativas.
Fonte: JOHNSON et AL (2009)
1.1.17.1.2MANDATORY
Segundo SARANG, P.G. et AL (2001), este (PROPAGATION_MANDATORY no Spring) atributo indica
que o método em questão deverá sempre ser invocado dentro do contexto de uma transação pré-existente. Portanto,
é madatório que o método cliente já tenha iniciado uma transação, que será propagada para o método com este
atributo. Caso o método cliente não tenha iniciado uma transação, o container lançará uma exceção
TransactionRequiredException.
Este atributo deve ser utilizado quando se faz necessário verificar se o método com este atributo foi invocado
dentro do contexto de uma transação gerenciada pelo cliente.
1.1.17.1.3REQUIRES_NEW
Segundo SARANG, P.G. et AL (2001), o atributo REQUIRES_NEW
(PROPAGATION_REQUIRES_NEW, no Spring), indica que um determinado deverá sempre ser executado dentro
de sua própria transação. Ele deve ser utilizado quando uma transação é necessária, porém, um possível rollbach
dentro desta transação não deve afetar a transação existente fora deste método.
O container irá criar um novo contexto transacional par ao método, antes dele ser invocado. Se o método está
sendo invocado dentro do contexto de uma transação, esta será suspensa e uma nova transação será criada. Assim
que o método completar a sua execução, o container irá realizar o commit da transação interna e retomar a transação
externa.
Segundo RICHARDS (2006), este atributo é muito útil quando uma atividade deve ser completada
independente do resultado da transação que a cerca. Um exemplo de uso deste atributo é auditoria. Por exemplo, na
maioria dos sistemas de comércio, cada ação deve ser registrada, independente do resultado final ser um sucesso ou
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 42/84
uma falha. Considerando uma situação na qual um comerciante está tentando vender uma ação. Uma transação JTA
inicia-se na invocação do método venderAcao() que, por sua vez, invoca o método realizarAuditoria(). Uma vez o
método realizarAuditoria() estando dentro da transação iniciada pelo método venderAcao(), as inserções na base
feitas pelo método realizarAuditoria() poderiam ser desfeitos caso ocorra uma falha durante a execução do método
venderAcao() e isto violaria a regra descrita acima, a qual diz que tudo deve ser registrado na tabela de auditoria,
independente do resultado da execução do método venderAcao(). Desta maneira, assinalando o método
realizaAuditoria() com o atributo transacional REQUIRES_NEW garantirá que as atualizações na tabela de auditoria
sejam gravadas independente do resultado obtido na execução do método vendeAcao().
A figura 6 ilustra o comportamento da transação com este atributo transacional:
Ilustração 6:Mecanismo de controle de transações declarativas.
Fonte: JOHNSON et AL (2009)
1.1.17.1.4SUPPORTS
Segundo SARANG, P.G. et AL (2001), a propriedade SUPPORTS (PROPAGATION_SUPPORTS no
Spring) indica ao container que o método associado irá utilizar uma transação caso alguma esteja disponível. No
entanto, caso não haja nenhum contexto transacional, então o método pode ser invocado fora de uma transação.
Segundo RICHARDS (2006), podemos considerar uma simples busca no banco de dados para recuperar o
total de vendas realizados por um determinado comerciante. Uma transação não é necessariamente requerida para
completar esta ação. Portanto, usando o atributo SUPPORTS, o container não iriá iniciar uma transação à partir da
invocação deste método. Entretanto, caso este método seja invocado dentro do contexto de uma transação, o
container à utilizadá.
1.1.17.1.5NOT_SUPPORTED
Segundo SARANG, P.G. et AL (2001), o atributo NOT_SUPPORTED
(PROPAGAGION_NOT_SUPPORTED, no Spring) indica ao container que o método indicado não deverá ser
executado dentro do contexto de uma transação. Caso ele tenha sido invocado dentro deste contexto, o container irá
suspender o contexto transacional do método cliente.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 43/84
Ainda segundo SARANG, P.G. et AL (2001), se um método é indicado como NOT_SUPPORTED, a
transação não será propagada para este método. Caso alguma exceção ocorra dentro do método marcado com o
atributo acima, esta não interferirá na transação do método que a invocou. Porém, ao término da execução deste
método, a transação original será retomada. Este atributo geralmente é utilizado quando uma aplicação precisa
interagir com um gerenciador de recursos que não suporta transações.
1.1.17.1.6NEVER
Segundo RICHARDS (2006), o atributo NEVER(PROPAGATION_NEVER, no Spring) indica ao
container que o método em questão não pode ser executado dentro do contexto de uma transação. Podemos notar a
diferença entre o atributo NOT_SUPPORTED e o atributo NEVER. Caso o método tenha o atributo
NOT_SUPPORTED, caso uma transação exista antes da invocação dele, o container irá suspender a transação atual
até que a execução termine e irá retomá-la apos isso. Entretando, com o atributo NEVER, caso uma transação já
exista quando o método é invocado, o container lançará uma exceção, indicando que a transação nãop é permitida. O
uso deste atributo pode levar à exceções inesperadas e indesejadas em tempo de execução. Sendo assim, ela deverá
ser utilizada apenas quando for estritamente necessário. Não há muitas situações onde este atributo é útil. Na dúvida,
deve-se sempre utilizar o atributo NOT_SUPPORTED.
A tabela à seguir resume o comportamento esperado em relação a cada um dos atributos transacionais:
TransactionAttribute
Client'sTransaction
ComponentMethod's
TransactionComment
RequiredNone T2
If no transaction exists, the servercreates one.
T1 T1If a transaction exists, the serveruses it.
RequiresNewNone T2
If no transaction exists, the servercreates one.
T1 T2If a transaction exists, the servercreates a new one.
MandatoryNone Error
If no transaction exists, an exceptionis thrown.
T1 T1If a transaction exists, the serveruses it.
Not SupprotedNone None
The server does not provide atransactional support.
T1 NoneThe server does not provide atransactional support.
If no transaction exists, the server
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 44/84
SupportsNone None If no transaction exists, the server
does not provide a transactionalsupport
T1 T1If a transaction exists, the serveruses it.
NeverNone None
The server does not provide atransactional support.
T1 ErrorIf a transaction exists, an exceptionis thrown.
Tabela 2: Resumo do comportamento dos atributos transacionaisFonte: SARANG, P.G. et AL (2001)
1.1.17.2Emprego dos Atributos Transacionais
Para SARANG, P.G. et AL (2001), as diferenças entre os diversos atributos transacionais são pequenas e
podem confundir quando se tenta determinar o melhor a ser usado; qual atributo manterá as propriedades ACID e o
quanto elas são necessárias.
Por exemplo, REQUIRES_NEW garante um maior nível de atomicidade e isolamento, porém, perdendo em
performance pelo custo de criar uma nova transação e gerenciar a existente. Outro fator que afetará a escolha do
atributo transacional à ser utilizado é o nível de suporte transacional que o processador transacional oferece. Por
exemplo, caso ele não suporte transações aninhadas, a aplicação também não suportará.
Segundo SARANG, P.G. et AL (2001), pode-se levar as considerações abaixo como uma diretriz para a
escolha dos atributos transacionais:
Usar o atributo REQUIRED sempre que um código necessitar mudar o valor de algum dado.
Usar o atributo SUPPORTS quando se necessita ler dados de uma fonte. Isto permitirá que o componente que
está invocando o método decida se deverá ou não utilizar uma transação.
Sempre que for necessára uma comunicação com recursos que não suportam processamento transacional,
deve-se utilizar o atributo NOT_SUPPORTED.
Quando se utiliza MDB (Message-Driven Beans), o atributo transacional deverá ser especificado para o
método onMessage(). Este tipo de componente apenas suporta os atributos REQUIRED e
NOT_SUPPORTED.
1.1.17.3Isolamento de uma Transação
Para SARANG, P.G. et AL (2001), a propriedade Isolamento de uma transação ACID requer que uma
transação opere sem levar em consideração e sem ser afetada por outra transação. Em um sistema concorrente, várias
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 45/84
transações podem estar acontecendo ao mesmo tempo e, frequentemente, sobre os mesmos dados. A isolamento das
transações é atingida por meio de bloqueio e serialização das requisições dos dados.
Bloqueio controla o acesso a um determinado dado. Os dois principais tipos de bloqueio são o bloqueio de
leitura e o bloqueio de escrita. O bloqueio de escrita é não exclusivo, ou seja, deixará com que várias transações leiam
o dado. O bloqueio de escrita é exclusivo, ou seja, apenas permitirá que uma única transação manipule os dados.
Serialização garante com que as transações concorrentes que estão em execução se comportem como se
estivessem executando em série.
Segundo RICHARDS (2006), isolamento é uma função inversamente proporcional entre a concorrência e a
consistência dos dados. Ao passo que aumentamos o isolamento da transação, aumentamos a consistencia dos dados
e diminuimos a concorrência no sistema. A ilustração 7 mostra este relacionamento:
Ilustração 7:Relação entre Isolamento, Concorrência e Consistência
Fonte: RICHARDS (2006),
Ainda segundo RICHARDS(2006), esta configuração causa impacto à performance e à integridade da
aplicação. A maioria dos servidores de aplicação e bancos de dados já tem configurações padrão que balanceiam
concorrência e consistência. De qualquer maneira, com EJB ou Spring, pode-se alterar estas configurações para
otimizar a aplicação de acordo com a necessidade. Abaixo seguem as possíveis configurações:
TransactionReadUncommited
TransactionReadCommited
TransactionRepeatableRead
TransactionSerializable
1.1.17.3.1TransactionReadUncommited
RICHARDS(2006) nos ensina que este é o nível mais baixo de isolamento suportado por ambos EJB e
Spring. Este tipo de configuração permite que as transações leiam dados não gravados permanentemente no banco de
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 46/84
dados por outras transações. Para ilustrar esta situação, pode-se imaginar uma determinada ação na bolsa com o
valor inicial de US$90,00. As transações A e B estão acessando os mesmos dados, sendo que a transação A realiza
atualizações nos dados e a transação B as lê. A ilustração 8 demonstra asituação:
Ilustração 8:Duas transações no modelo TransactionReadUncommited.
Fonte: RICHARDS (2006)
Pode-se notar no diagrama acima que no momento t2, a transação A realiza uma atualização no banco de
dados e a transação B, no momento t3, consegue ver a alteração sem que ela esteja gravada permanentemente no
banco. Pode-se notar também que a transação A não está isolada da transação B e, caso a transação A seja desfeita,
os dados que a transação B acessou estarão incorretos. Portanto, esta configuração de isolação viola as propriedades
ACID e não é suportada pela maioria dos bancos de dados.
1.1.17.3.2TransactionReadCommited
Segundo os ensimanentos de RICHARDS (2006), este tipo de configuração de isolamento permite que
multiplas transações concorrentes podem acessar os mesmos dados, porém, dados não gravados permanentemente
na base de dados não podem ser vistos por outras transações até que sejam de fato gravados. Utilizando-se do
mesmo exemplo utilizado acima, com as transações A e B, o diagrama fica desta maneira:
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 47/84
Ilustração 9:Duas transações no modelo TransactionReadCommited.
Fonte: RICHARDS (2006)
Nota-se que na ilustração 9, no momento t2 a transação A realiza uma atualização. No tempo t3, a transação
B não tem acesso aos dados alterados pela transação A pelo fato de não estarem gravados permanentementes. Este é
um bom nivel de isolamento, pois permite que a transação B acesse os dados e esconde as atualizações não gravadas
por outras transações, até que estas se completem e gravem os dados. Este é o nível padrão de isolamento para a
maioria dos bancos de dados e é suportado pela maioria dos bancos de dados.
1.1.17.3.3TransactionRepeatableRead
Segundo RICHARDS(2006), este nível de isolamento mantém todas as transações isoladas umas das outras.
Este tipo de isolamento assegura que, sempre que uma transação recupera um conjunto de dados do banco de dados,
este mesmo conjunto de dados será sempre recuperado sempre que um comando de busca for executado por esta
transação (a menos que a própria transação altere algum destes dados). Para ilustrar este nivel de isolamento, pode-se
assumir que existe um comando de busca que procura na base de dados por todas as ações vendidas durante um dia.
A transação A realiza uma inserção na base de dados durante a execução da transação B, que realiza a pesquisa.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 48/84
Ilustração 10:Duas transações no modelo TransactionRepeatableRead.
Fonte: RICHARDS (2006)
Nota-se na figura acima que, apesar de ocorrer uma inserção de dados na base de dados pela transação A, o
conjunto de dados recuperado pela transação B é o mesmo, mesmo depois da gravação permanente realizada pela
transação A em t3. Os dados novos apenas serão disponíveis para a transação B após ela ter finalizado. Nota-se
também que com esta configuração de isolamento de transação, ambos os bloqueios (de leitura e escrita) são
colocados nos dados que estão sendo buscados. Portanto, este tipo de configuração deve ser utilizado com cuidado,
pois as outras transações devem esperar (ou falhar) até que os dados utilizados pela transação com leitura repetida se
completar.
1.1.17.3.4TransactionSerializable
RICHARDS (2006) nos ensina que este é o nível mais baixo de isolamento suportado pelo Java. Com este
nível de isolamento, a apenas uma transação é dada a permissão de acesso aos dados, enquanto a outra transação
fica suspensa. A concorrência é significantemente impactada com esta configuração e, por outro lado, a consistência
aumenta bastante. Usando o mesmo exemplo usado nas sessões 2.5.3.3.1 e 2.5.3.3.2, a ilustração 11 mostra de que
maneira se comportam as transações com a configuração em questão:
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 49/84
Ilustração 11:Duas transações no modelo TransactionSerializable.
Fonte: RICHARDS (2006)
Nota-se que a transação B fica suspensa durante todo o tempo de execução da transação A. Embora todos
os fornecedores de bancos de dados dêem suporte à este nivel de isolamento, o Oracle o trata de maneira diferente.
Ele utiliza-se de versionamento de dados, que não irá suspender de fato a transação B. Porém, caso a transação B
tente acessar os mesmos dados utilizados pela transação A, o Oracle retornará a mensagem de erro ORA-08177,
indicando que não poderá serializar o acesso o acesso para esta transação.
JTA E JTS
Segundo RICHARDS (2006), para gerenciar efetivamente transações em aplicações Java, os
desenvolvedores não necessitam saber os detalhes de implementação do Java Transaction Services (JTS). Porém,
independente de usar Spring Framework ou EJB, é importante entender as limitações que existem no processamento
de transações distribuidas em Java.
Ainda segundo RICHARDS (2006), independente do framework que está sendo utilizado, a maioria das
aplicações Java utilizam-se da Java Transaction API (JTA) para o gerenciamento de transações. JTA é a interface
utilizada pelos desenvolvedores para controlar as transações. Por outro lado, Java Transaction Services (JTS) é um
serviço subjacente que implementa a JTA e é utilizado pela maioria dos servidores de aplicação open-source (há
outros serviços de transação no mercado, diferentes do JTS e que também podem ser utilizados para este fim).
RICHARDS (2006) ainda nos mostra que há poucas interfaces as quais os desenvolvedores devem se
preocupar quando se fala em controlar transação. Por exemplo, quando usamos Controle de Transação
Programático, a única interface que deve ser utilizada é a javax.transaction.UserTransaction. Esta interface permite
começar uma transação, “commitar” uma transação, desfazer uma transação e recuperar o seu status. Quando usamos
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 50/84
o Controle de Transação Declarativo usando EJB, estamos primáriamente preocupados com o método
setRollbackOnly() da interface javax.ejb.EJBContext. Há muito mais que pode ser feito com as interfaces providas
pelo pacote javax.transaction, porém desenvolvedores não as usam frequentemente.
8.
1.1.18Interface UserTransaction
Conforme CHEUNG; MATENA (1999) nos ensinam, a interface javax.transaction.UserTransaction fornece
à aplicação a possibilidade de controlar os limites de transação programáticamente.Esta interface deve ser utilizada
por programas clientes em Java ou por EJB.
RICHARDS (2006) nos diz que os únicos métodos desta interface aos quais os desenvolvedores devem ter
conhecimento estão enumerados na Tabela 1, abaixo:
Retorno Método
void begin()
void commit()
int getStatus()
void rollback()
Tabela 2: Métodos da interface UserTransactionFonte: JavaEE 6 API Javadoc
1.1.18.1javax.transaction.UserTransaction.begin()
Segundo RICHARDS (2006), o método begin() é utilizado no Modelo de Transação Programática para
iniciar uma transação e associá-la à thread corrente. Este método irá lançar a exceção NotSupportedException caso a
thread corrente já esteja associada à uma transação e não suporte transaçoes aninhadas.
1.1.18.2javax.transaction.UserTransaction.commit()
Ainda segundo RICHARDS (2006), o método commit() tem como função salvar permanentemente os efeitos
dos comandos da transação associada à thread corrente e também finalizá-la. Este método também irá desassociar a
transação da thread corrente. Em Java, uma única transação deverá ser associada à uma única thread.
1.1.18.3 javax.transaction.UserTransaction.rollback()
RICHARDS (2006) nos ensina que o método rollback() desfaz os efeitos de todos os comandos executados
dentro da transação, a termina e desassocia da thread corrente. Este método é utilizado no Modelo de Transação
Programático.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 51/84
1.1.18.4javax.transaction.UserTransaction.getStatus()
Sabe-se que o método getStatus() também é utilizado no Modelo de Transação Programática para retornar
um valor do tipo Inteiro que indica o status da transação corrente. À princípio, o valor retornado parece sem sentido,
mas pode-se utilizar a interface javax.tran saction.Status para se definir o status da transação atual.
1.1.19Interface TransactionManager
Segundo CHEUNG; MATENA (1999), esta interface permite ao servidor de aplicação controlar os limetes
da transação em nome da aplicação que está sendo gerenciada. Por exemplo, o container EJB gerencia o estado das
transações para os componentes EJB transacionais. Para tal, ele utiliza principalmente a interface TransactionManager,
demarcando os limites da transação nos quais as operações afetam seu contexto. O Gerenciador de Transações
mantém a associação do contexto da transação com threads como parte de sua estrutura interna de dados. O
contexto transacional de uma thread pode ser null ou estar associado à uma transação global. Várias threads podem
estar concorrentemente associadas á mesma transação global.
Ainda segundo CHEUNG; MATENA (1999), cada contexto transacional é encapsulado por um objeto do
tipo Transaction, que é utilizado para realizar operações específicas para a transação alvo, independente do contexto
transacional da thread em questão.
Entende-se que a interface javax.transaction.TransactionManager é utilizada primariamente dentro do Modelo
de Transação Declarativa. Para o Modelo de Transação Programática pode-se fazer com a interface
TransactionManager a mesma coisa que se faz com a interface UserTransaction. Porém, neste modelo, aconselha-se à
deixá-la de lado, a menos que se apresente a necessidade de suspender ou retomar uma transação(RICHARDS, M. ,
2006).
A tabela 2 nos mostra os principais métodos da interface TransactionManager
Retorno Método
void begin()
void commit()
int getStatus()
void rollback()
Transaction suspend()
void resume(Transaction tobj)
Tabela 3: Principais métodos da interface TransactionManaterFonte: JavaEE 6 API Javadoc
1.1.19.1javax.transaction.TransactionManager.suspend()
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 52/84
Este método, segundo RICHARDS (2006), é utilizado nos Modelos de Transação Declarativa ou
Programática para suspender a transação associada à thread corrente. Ele retorna uma referência à transação
suspensa ou null, caso não haja transação associada à thread. Este método é geralmente utilizado caso a transação
necessite ser suspensa para a execução de códigos ou stored procedures que não são comátíveis com o ambiente de
transações distribuídas.
1.1.19.2Javax.transaction.TransactionManager.resume()
RICHARDS (2006) nos ensina que este métodos é usado em ambos os Modelos de Transação:
Programativo e Declarativo. Tem como função retomar uma transação previamente suspensa. Recebe como
parâmetro uma referência à transação suspensa, associa esta transação à thread corrente e a retoma.
PADRÕES DE PROJETO RELACIONADOS À TRANSAÇÕES
Nesta sessão, demonstraremos alguns padrões de design de transações existentes. Serão detalhados os
padrões Client Owner Transaction Design Pattern, Domain Service Owner Transaction Design Pattern e Server
Delegate Owner Transaction Design Pattern, todos explicados por RICHARDS (2006).
1.1.20Padrão de Projeto CLIENT OWNER TRANSACTION
Como o nome sugere, o componente Client Delegate possui a transação. Embora este padrão seja muito
utilizado quando utiliza-se de EJB e de SessionBeans remotos junto com uma camada cliente baseada em web ou em
Swing, também pode ser utilizado por aplicações que contém serviços locais e bem granularizados, na qual são
necessárias várias requisições à diferentes serviços para atender à uma requisição do cliente.
1.1.20.1Contexto
Embora indesejável, algumas vezes é necessário forçar o gerenciamento da transação para a camada cliente
dentro de uma aplicação Java Enterprise. Considere a comum situação na qual uma simples requisição é feita por
meio do cliente, porém, para poder atendê-la, serão necessárias multiplas chamadas (remotas) ao servidor. Esta
situação frequentemente ocorre quando os serviços do domínio são muito granularizados e não existem serviços
agregados. Quando este tipo de situação ocorre, o controle da transação é colocado na camada de apresentação
para garantir a manutenção das propriedades ACID.
O exemplo abaixo mostra uma situação na qual o cliente recebe uma requisição de comercialização de um
titulo de renda fixa. Quando o título é colocado à venda, o cliente executa os métodos realizaVenda() e
executaVenda() dentro de uma mesma transação. O trecho de código abaixo ilustra a situação:
public void comercializaTituloRendaFixa(DadosVenda dados)
throws Exception{
try {
Venda venda = vendaService.realizaVenda(dados);
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 53/84
execucaoService.executaVenda(venda);
} catch (Exception e) {
log.fatal(e);
throw e;
}
}
Pelo fato destas duas ações terem que ser tratadas como um processo único, eles devem estar encapsulados
em uma transação. Sem uma transação mantida pelo cliente, o processo acima ilustrado não manteria as propriedades
ACID, pois as atualizações realizadas pelo serviço realizaVenda() seriam salvos antes da invocação do serviço
executaVenda().
Mesmo existindo várias maneiras de se re-arquitetar a situação acima descrita, ainda haverão situações que
necessitaram do gerenciamento da transação no cliente. Uma das grandes desvantagens relacionadas à este design é
que ele acaba colocando muitas responsabilidades de infra-estrutura no cliente.
1.1.20.2QUANDO USAR
Quando o cliente necessita realizar várias chamadas (remotas ou locais) para o principal serfiço, afim de
atender uma unica requisição de negócios.
As propriedades ACID deverão ser mantidas durante o processo, requerendo uma transação
Os serviços de domínio são muito granularizados e não existe agregação de serviços para combinar os serviços
necessários para atender uma requisição de negócios.
Não é possível re-arquitetar a aplicação para gerar um único serviço de domínio que seja capaz de encapsular
todas as chamadas aos serviços (locais ou remotos) necessários para atender a requisição de negócios.
1.1.20.3SOLUÇÃO
A solução apra o cenario acima descrito é a utilização do padrão Client Owner Transaction Design Pattern
como a estratégia global de design de transações. Este padrão usa um modelo de responsabilidade componente, que
joga a responsabilidade do controle da transação no cliente. A ilustração 12 mostra este padrão aplicado aos
frameworks Spring e EJB:
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 54/84
Ilustração 12:Diagrama do Padrão de Projetos Client Owner Transaction.
Fonte: RICHARDS (2006)
Conforme a ilustração 5 mostra, o único componente responsável por controlar a transação é o
ClientBusinessDelegate. Se este componente for gerenciado pelo Spring Framework, ele poderá utilizar-se do
Modelo de Transação Declarativo. Caso contrário, ele deverá utilizar-se do Modelo de Transação Programático.
Neste padrão de projetos, os serviços de domínio deverão utilizar transações declarativas, pois um contexto
transacional estabelecido no cliente não pode ser propagado para serviços de domínio remotos ou locais utilizando
transações programáticas. Contudo, o contexto transacional criado pelo cliente poderá ser propagado aos serviços de
domínio, caso estejam utilizando transações declarativas.
Como este padrão especifica, os componentes de domínio que realizam inserções, atualizações e deleções na
base de dados deverão ter o atributo transacional MANDATORY atribuído à eles. Ainda mais importante, os
métodos de domínio não deverão marcar a transação para ser desfeita (rollback) por meio de exceções da aplicação
(checked exceptions). Marcar a transação para ser desfeita é uma maneira de controlar a transação, controle este que
deverá ficar sob responsabilidade do componente controlador da transação. Neste caso, o componente responsável
pelo controle de transação é o ClientBusinessDelegate, não os serviços de domínio. Marcando-se a transação para
ser desfeita nos serviços de dominio por meio de exceções da aplicação proibirá o ClientBusinessDelegate de tomar
alguma ação corretiva para, programaticamente, resolver o problema e assim continuar com a transação.
Nota-se que neste padrão de projetos, há uma mistura dos modelos de transação programática e declarativa.
Embora isto geralmente não seja uma boa prática, quando se usa uma transação baseada no componente cliente, isto
é uma prática aceitável e necessária.
1.1.21Padrão de Projeto DOMAIN SERVICE OWNER TRANSACTION
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 55/84
O padrão de projetos Domain Service Owner Transaction é o padrão mais comumente encontrado e aplicado
às arquiteturas de aplicações Java. Neste padrão, o serviço de domínio é o responsável pelo controle da transação.
Em EJB, o serviço de domínio é implementado como um Stateless SessionBean, usando o Modelo de Transações
Declarativas para controlar a transação. No Spring, o serviço de domínio é implementado como um objeto Java
comum (Plain Old java Object – POJO) que também usa transações declarativas.
1.1.21.1Contexto
A maioria dos arquitetos e desenvolvedores java concorda que a camada do servidor deve ser responsável
por gerenciar as transações. Em primeiro lugar, pode-se não saber quais os tipos de clientes acessando os serviços;
em segundo lugar, assinalando a responsabilidade do controle da transação para a camada cliente coloca muita
responsabilidade sobre ela, que deveria ser responsável por logicas de apresentação e não por lógicas da camada de
servidor, como o controle de transação; outro ponto é que a performance sempre acaba sendo menor nas arquiteturas
em que o cliente controla a transação, pelo fato de o cliente fazer multiplas chamadas remotas ao servidor, o que
aumenta a conversação entre cliente e servidor e degrada a performance; por fim, o controle de transações na camada
cliente adiciona uma complexidade desnecessária às estratégias de controle de transação.
Pelas razões acima citadas, as aplicações Java Enterprise são geralmente projetadas com uma camada de
serviços que lida com a requisição de negócios como se fosse uma única unidade de trabalho. Isto, em geral, simplifica
a arquitetura e aumenta a performance da aplicação. Neste padrão de projetos, as questões principais são: a) Quais
os componentes deverão ser responsáveis por iniciar a transação, finalizar e gravar os dados da transação (commit),
marcar a transação para ser desfeita (rollback) e b) De que maneira a transação será propagada ao framework de
persistência.
Considerando o exemplo em que o cliente está realizando uma requisição de comercialização de um título de
renda fixa, a qual envolve a execução dos métodos realizaVenda() e executaVenda(). Utilizando o padrão de projetos
Domain Service Owner Transaction, a ação seria realizada conforme o trecho de código abaixo:
public void comercializaTituloRendaFixa(DadosVenda dados) throws Exception{
try {
//código relacionado à venda
comercializacaoService.comercializaTitulo(dados);
} catch (Exception e) {
log.fatal(e);
throw e;
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 56/84
}
}
Pelo fato de o cliente fazer apenas uma única requisição ao servidor, o cliente não necessita gerenciar a
transação, mesmo que esta única requisição envolva a invocação de diversos métodos de diversos serviços alocados
na camada do servidor. Portanto, o controle da transação deverá estar dentro de algum dos serviços envolvidos nesta
requisição.
1.1.21.2QUANDO USAR
O cliente realiza apenas uma única requisição aos objetos de serviço para atender uma requisição de negócios
do cliente
As propriedades ACID deverão ser mantidas , o que significa que o processamento de uma transação é
requerido para manter a integridade dos dados
Os serviços de domínio são pouco granularizados e/ou se comunicam entre si para realizar a agregação de
requisições de serviços.
1.1.21.3SOLUÇÃO
A solução para este cenário típico de transações gerenciadas pelo servidor é o uso do padrão de projeto
Domain Service Owner Transaction. Este padrão utiliza-se de um modelo de responsabilidade componente no qual
toda a obrigação do controle de transação fica à cargo dos serviços de domínio, sendo eles remotos ou locais. A
ilustração 13 exemplifica o modelo:
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 57/84
Ilustração 13:Diagrama do Padrão de Projetos Domain Service Owner Transaction.
Fonte: RICHARDS (2006)
Nota-se, analisando o diagrama acima, que não há outro componente na aplicação que é responsável pela
lógica de controle de transação além das classes de serviço de domínio (Domain Service). Nenhum outro componente
dentro da arquitetetura mostrada acima necessita saber que o processamento transacional está ocorrendo.
Independente do framework utilizado para implementar este padrão de projetos (Spring ou EJB), os componentes de
serviço de domínio estão utilizando transações declarativas e têm, em seus métodos que manipulam dados no banco
de dados (inserção, atualização e deleção) o atributo transacional REQUIRED. Para as operações de leitura, os
métodos tem o atributo transacional SUPPORTS. O cerne deste padrão está no fato de que o ponto de entrada para
a camada dos serviços de domínio irá criar e obter o controle sobre a transação e todos os outros serviços invocados
por este primeiro serviço estarão dentro da transação criada por ele.
O atributo transacional REQUIRED é utilizado neste padrão pelos serviços de domínio ao invés do atributo
REQUIRES_NEW nas conversações entre dois ou mais serviços de domínio. Este padrão de projetos de transações
é relativamente fácil de ser implementado e mantido pelo fato de apenas os serviços de domínio terem lógica de
controle de transação e a necessidade de configuração em outros códigos ser mínima.
Este é o modelo mais comum de transações usado para as aplicações Java Enterprise. Deve ser utilizado
quando os serviços de domínio são pouco granularizados e quando o cliente realiza apenas uma única requisição ao
servidor para atender uma necessidade de negócios. Este modelo é particularmente importante quando se usa cientes
de web services ou pacotes de terceiros que não são facilmente modificados.
1.1.22Padrão de Projeto SERVER DELEGATE OWNER TRANSACTION
Este padrão de projetos de transações é aplicável quando a aplicação está utilizando os padrões de projeto
Command e Server Delegate. Com este padrão o componente Server Delegate, que é a entrada remota para o
servidor, obtém a transação e é responsável por todo o seu controle.
O pardão de projetos Command é muito útil, pois resolve diversas questões relacionadas ao controle de
transação relaizado pelo cliente. O princípio básico por trás deste padrão está no fato da funcionalidade cliente estar
em uma classe command e esta ser enviada para o servidor executá-lo. Este comando deve ter uma ou mais
invocações aos métodos dos serviços de domínio. Portanto, estas invocações são todas executadas no servidor por
meio da respectiva implementação do objeto command, ao invés do cliente. O uso deste padrão permite que sejam
realizadas requisições singulares ao servidor pelo cliente e permite que o processamento da transação seja realizado
pelo servidor.
O padrão de projetos Server Delegate é similar ao Command, porém, ao invés de se montar um framework,
este padrão simplesmente coloca a lógica de negócios do cliente (no que diz respeito às chamadas de métodos de
domínio) dentro de um componente delegador dentro do servidor. O resultado é o mesmo, pois o processamento
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 58/84
transacional é movido para o servidor e as diversas invocações à serviços necessárias para preencher uma requisição
de negócios do cliente se reduzem a apenas uma.
O padrão de projetos Server Delegate Owner Transaction é um caso especial do padrão Domain Service
Owner Transaction. A principal diferença é que, utilizando o padrão Command teremos um único objeto responsável
pelo controle de transação, ao invés de haver vários componentes com esta função. Por exemplo, se a aplicação
tivesse quarenta componentes de serviço de domínio, teria-se quarenta componentes controlando as transações, ao
passo que neste padrão haveria apenas uma classe (Command Processor) controlando as transações.
1.1.22.1Contexto
O trecho de código abaixo exemplifica um objeto clente que necessita a realização de várias chamadas aos
serviços de domínio para preencher uma requisição de negócios do cliente:
public void comercializaTituloRendaFixa(DadosVenda dados) throws Exception{
InitialContext ctx = new InitialContext();
UserTransaction txn = (UserTransaction) ctx
.lookup("java:comp/UserTransaction");
try {
txn.begin();
Venda venda = vendaService.realizaVenda(dados);
execucaoService.executaVenda(venda);
txn.commit();
} catch (Exception e) {
txn.rollback();
log.fatal(e);
throw e;
}
}
Neste caso, o cliente deverá utilizar-se do Modelo de Transações Programáticas para assegurar que as
propriedades ACID da transação sejam atendidas em uma única unidade de trabalho. Nesta situação o cliente é
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 59/84
responsável pelo controle da transação e a performance é impactada por haver várias invocações de métodos de
serviços de domínio.
Para simplificar a situação acima descrita e aplicar o padrão de projetos Server Delegate Owner Transaction,
a lógica deverá ser removida do componente cliente e deverá existir apenas uma invocação de método ao servidor.
Para tal, pode-se utilizar dos padrões Command e Server Delegate mutuamente. O código trecho de código abaixo
exemplifica a modificação do componente cliente:
public void comercializaTituloRendaFixa(DadosVenda dados) throws Exception{
try {
ComercializaTituloCommand command = new ComercializaTituloCommand();
command.setDadosVenda(dados);
CommandHandler.executar(command);
} catch (Exception e) {
txn.rollback();
log.fatal(e);
throw e;
}
}
1.1.22.2Quando usar
Quando o padrões de projetos Command ou Server Delegate são ultilizados na arquitetura de comunicação
entre o cliente e o servidor.
Quando o cliente realiza apenas uma requisição ao servidor para preencher a necessidade de negócios.
Quando as propriedades ACID devem ser mantidas, necessitando para isso o processamento de uma
transação.
Quando os objetos de serviços de domínio são implementados como POJO, podendo ser remotos ou locais.
Quando o Command Processor ou o Server Delegate é o único ponto de entrada aos serviços de domínio, na
camada cliente.
1.1.22.3Solução
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 60/84
Quando usando o padrão Command ou Server Delegate, o padrão Server Delegate Owner Transaction pode
ser utilizado para especificar toda a estratégia de controle de transações para este tipo de arquitetura de aplicação.
Este padrão delega toda a responsabilidade do controle da transação ao Command Processor, como mostra a
ilustração 14:
Ilustração 14:Diagrama do Padrão de Projetos Service Delegate Owner Transaction.
Fonte: RICHARDS (2006)
O Server Delegate usa transações declarativas e nos métodos de alteração de dados tem o atributo
transacional REQUIRED, enquanto nos métodos relacionados à busca está definido o atributo SUPPORTS. Este
componente também é o responsável por desfazer uma transação, caso ocorra algum erro durante seu processamento
(application exception).
As arquiteturas utilizadas neste padrão de projeto são distintas. No caso do padrão Command, o Sever
Delegate é implementado como o Command Processor, que aceita um objeto do tipo Command e o executa. O uso
de interfaces assegura que os componentes Command Handler, Command Processor, Command Interface
Implementation e Command Interface se mantenham genéricos. As transações criadas pelo server Delegate são
propagadas aos objetos de serviço de domínio invocados por ele.
No caso do padrão Server Delegate, o objeto Server Delegate serve para o cliente como uma faixada para os
serviços de domínio. Neste padrão também, a lógica do cliente é movida para um componente dentro do servidor,
A principal desvantagem deste padrão está no fato de o componente delegador, no servidor, conter lógicas
que deveriam estar no lado do cliente. Adicionalmente, a implementação deste padrão pode ser dificultada pelo
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 61/84
componente delegador, muitas vezes, estár fortemente acoplado ao framework de visualização. Por exemplo, quando
se utiliza o framework Struts, no qual a classe Action pode ser utilizada como delegador, torna-se difícil mover a
lógica para o servidor pelo código conter referências à objetos da camada de visualização, como HttpServletRequest,
HttpServletResponse, HttpSession, entre outros.
A principal vantagem de ambos os padrões acima descritos está em os serviços de domínio serem
implementados como POJOs ao invés de EJB, o que os torna mais fáceis de testar. Outro ponto importante é que o
delegador geralmente é implementado como um componente singleton, ou seja, toda a lógica de controle de transação
está em apenas um objeto no sistema inteiro, tornando-o assim fácil de manter e implementar.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 62/84
Controle de transação no spring framework
Segundo JOHNSON et AL (2009), o controle transacional é um dos motivos mais convincentes para se
utilizar o Spring Framework, pois provém uma abstração consistente do controle de transações, que traz os seguintes
benefícios:
Fornece um modelo de programação consistente através de diversas APIs como JTA, JDBC, Hibernate, JDO
entre outros.
Suporta o modelo de transações declarativas
Fornece uma API para o controle programático de transações mais simples do que APIs como JTA.
Fornece boa integração com as abstrações de acesso à dados do próprio Spring.
Sabe-se que o Spring Framework oferece suporte para ambos os modelos transacionais, declarativo e
programático. O suporte do Spring Framework se difere muito do fornecido pelo EJB, que é acoplado à
implementação da Java Transaction API (JTA). Desta maneira, o Spring emprega um mecanismo de callback que
abstrai a implementação da transação do código transacional. De fato, o suporte à transações oferecido pelo Spring
não necessáriamente necessita de uma implementação da JTA. Caso a aplicação utilize-se de um único recurso
persistente, poderá ser utilizado o suporte transacional fornecido pelo mecanismo de persistência, o que inclui JDBC,
Hibernate, Java Data Objects (JDO) e Object Relational Bridge (OJB). No entanto, caso a aplicação esteja sendo
executado em um ambiente de transações distribuídas, o Spring também poderá suportá-lo, utilizando uma
implementação do JTA de terceiros. (WALLS; BREIDENBACH, 2007)
ESCOLHENDO UM GERENCIADOR DE TRANSAÇÕES
Segundo WALLS; BREIDENBACH (2007), o Spring não gerencia diretamente as transações. Ao invés
disso, ele tem uma seleção de genciadores de transação que delegam a responsabilidade do controle da transação
para uma implementação específica para cada plataforma, provida pelo JTA ou pelo próprio mecanismo de
persistência. Os gerenciadores de transação do Spring estão listados na tabela 4:
Gerenciador de Transação (org.springframework.*) Usa-se...
jca.cci.connection.CciLocalTransactionManager
Quando necessita-se utilizar o suporte doSpring Framework para a Arquitetura deConectores J2EE (J2EE Connector Archtecture -JCA) e a Interface de Clientes Comuns(Common Client Interface - CCI)
jdbc.datasource.DataSourceTransactionManager
Quando se trabalha com o suporte para aabstração do Spring para JDBC. Também útilquando se utiliza o iBATIS para persistência
jms.connection.JmsTransactionManager Quando se trabalha com JMS 1.1+
jms.connection.JmsTransactionManager102 Quando se trabalha com JMS 1.0.2
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 63/84
orm.hibernate.HibernateTransactionManagerQuando se trabalha com Hibernate 2 parapersistência
orm.hibernate3.HibernateTransactionManagerQuando se trabalha com Hibernate 3 parapersistência
orm.jdo.JdoTransactionManager Quando se trabalha com JDO
orm.jpa.JpaTransactionManagerQuando se trabalha com Java Persistence API(JPA) para persistência
orm.toplink.TopLinkTransactionManagerQuando se trabalha com o TopLink, da Oracle,para persistência
transaction.jta.JtaTransactionManagerQuando se trabalha com transações distribuídasou quando nenhum outro gerenciador detransação atende às necessidades
transaction.jta.OC4JJtaTransactionManagerQuando se trabalha com o container JEE OC4Jda Oracle
transaction.jta.WebLogicJtaTransactionManagerQuando se trabalha com transações distribuídassendo executadas no servidor de aplicaçãoWebLogic
Tabela 4: Gerenciadores de Transação x Situações de UsoFonte: WALLS; BREIDENBACH (2007)
Ainda segundo WALLS; BREIDENBACH (2007), cada um destes gerenciadores de transação servem
como uma faixada para a implementação específica de cada forma de plataforma. Isto permite que se utilize o Spring
Framework para o controle de transação com pouca influência do mecanismo de persistência escolhido. A ilustração
15 mostra o relacionamento entre os gerenciadores de transação e as implementações subjacentes do mecanismo de
persistência.
Ilustração 15:Relação entre os gerenciadores de transação e os mecanismos de persistência.
Fonte: WALLS; BREIDENBACH (2007)
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 64/84
1.1.23Transações JDBC
WALLS; BREIDENBACH (2007) ensinam que, caso esteja-se utilizando JDBC para a persistência da
aplicação, a classe DataSourceTransactionManager irá lidar com com os limites transacionais. Para que esta classe
seja referenciada na aplicação, deverá ser introduzido o seguinte trecho de código no arquivo applicationContext.xml:
<bean id="transactionManager" class="org.springframework.jdbc.
datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Nota-se que a propriedade dataSource é definida como uma referência à um bean com este nome. Presume-
se que este bean seja um objeto do tipo javax.sql.DataSource e esteja definido em outro local do arquivo de definição
de contexto. Por trás dos panos, a classe DataSourceTransactionManager controla as transações por meio de
chamadas à classe java.sql.Connection, obtida por meio da classe DataSource. Ele termina uma transação pelo
método commit() e a desfaz, caso necessário, com a invocação do método rollback().
1.1.24Transações Hibernate
Segundo WALLS; BREIDENBACH (2007), caso esteja-se utilizando de Hibernate como mecanismo de
persistência de dados, deve-se utilizar a classe HibernateTransactionManager. Para as versões do Hibernate 2.x, a
declaração do transactionManager deverá ser conforme trecho de código abaixo:
<bean id="transactionManager" class="org.springframework.
orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
Caso a versão do Hibernate seja 3.x, a declaração deverá ficar desta maneira:
<bean id="transactionManager" class="org.springframework.
orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 65/84
A propriedade sessionFactory deverá ser atrelada à um objeto SessionFactory, existente na biblioteca do
Hibernate, e definido em outro ponto do arquivo de definição de contexto.
A classe HibernateTransactionManager delega a responsabilidade do controle da transação à um objeto da
classe org.hibernate.Transaction, recuperado da sessão do Hibernate. Caso a transação seja completa com sucesso,
o HibernateTransactionManager executará o método commit() no objeto Transaction. Da mesma maneira, se a
transação falhar, será executado o método rollback() neste objeto.
1.1.25Transações JPA
Ainda segundo WALLS; BREIDENBACH (2007), para que as transações sejam coordenadas quanto se
utiliza a Java Persistence API (JPA), deve-se escolher a classe JpaTransactionManager e referenciá-la conforme
segue:
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
A classe JpaTransactionManager apenas necessita ser ligada à uma fábrica de gerenciadores de entidade
(qualquer implementação de javax.persistence.EntityManagerFactory), que colaborará com o EntityManager criado
pela fábrica para conduzir as transações. Além de aplicar transações às operações JPA, este gerenciador também
suporta transações em operações simples utilizando JDBC no mesmo DataSource utilizado pelo EntityManager. Para
que isto de fato funcione, deve-se atrelar ao transactionManager uma implementação de JpaDialect. Caso queira-se
configurar um dialeto do tipo TopLinkJpaDialect, deve-se adicionar o trecho de código abaixo:
<bean id="jpaDialect"
class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
Este dialeto deverá ser referenciado na declaração do transactionManager, conforme segue:
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 66/84
É importante atentar-se para o fato de que as implementações dos JpaDialect deverão suportar acesso misto
JPA/JDBC. Todas as implementações do JpaDialect do Spring específicas dos fornecedores (HibernateJpaDialect,
OpenJpaDialect e TopLinkJpaDialect) suporta este tipo de acesso. Por outro lado, o DefaultJpaDialect não suporta.
1.1.26Transações JDO
WALLS; BREIDENBACH (2007) ensinam que ao utilizar Java Data Objects (JDO), o gerenciador de
transações que deverá ser utilizado será o JdoTransactionManager, declarado da seguinte maneira:
<bean id="transactionManager"
class="org.springframework.orm.jdo.JdoTransactionManager">
<property name="persistenceManagerFactory"
ref="persistenceManagerFactory" />
</bean>
Ao JdoTransactionManager deverá ser atrelada uma instância de javax.jdo.PersistenceManagerFactory à
propriedade persistenceManagerFactory. Nos bastidores, este gerenciador de transações também irá executar o
método commit() ao finalizar uma transação com sucesso e o método rollback() caso ela falhe.
1.1.27Transações JTA
Segundo WALLS; BREIDENBACH (2007), caso nenhum dos outros gerenciadores de transação não
atendam à necessidade da aplicação ou caso as transações da aplicação abranjam multiplas fontes de transação (por
exemplo, dois ou mais bancos de dados), será necessário utilizar o JtaTransactionManager:
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName"
value="java:/TransactionManager" />
</bean>
JtaTransactionManager delega a responsabilidade pelo controle da transação para alguma implementação da
JTA, que especifica uma API padrão para a coordenação de transações. A propriedade name do transactionManager
especifica o gerenciador de transações JTA a ser buscado por meio de seu nome JNDI.
SINCRONIZAÇÃO DE RECURSOS COM TRANSAÇÕES
Estando clara a maneira com que os gerenciadores de transação são interligados com os recursos que
precisam estar sincronizados com as transações (para o HibernateTransactionManager deverá ser atrelado o recurso
transacional SessionFactory, por exemplo), segundo JOHNSON et AL (2009), independente do framework de
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 67/84
persistência utilizado pela aplicação, o Spring assegura que estes recursos sejam manipulados
(criados/destuídos/reutilizados) adequadamente, por meio da plataforma PlataformTransactionManager.
1.1.28Abordagem alto-nível
Para JOHNSON et AL (2009) a abordagem mais recomendada é a utilização da API de mais alto nível do
Spring para a integração com os mecanismos de persistência. Esta API não substitui a API nativa dos mecanismos de
persistência, mas sim, manipula a criação, reuso e destruição do recurso sincronizado à transação e seus
mapeamentos de exceções para que o código que acessa os dados não tenha esta responsabilidade.
Esta abordagem se dá por meio das classes JdbcTemplate, JdoTemplate, JpaTemplate e HibernateTemplate.
1.1.29Abordagem baixo-nivel
Ainda para JOHNSON et AL (2009) , em um nível mais baixo, existem classes como DataSourceUtils (para
JDBC), SessionFactoryUtils (para Hibernate), PersistenceManagerFactoryUtils (para JDO), entre outras, utilizadas
em situações em que é mais propício para a aplicação utilizar os recursos nativos das APIs de persistência. Estas
classes asseguram que as instâncias obtidas por meio delas sejam gerenciadas pelo Spring Framework, com uma
transação sincronizada à eles (opcionalmente).
Como exemplo, pode-se utilizar a classe DataSourceUtils. Ao invés de invocar o método getConnection() no
objeto DataSource, utilizando-se do Spring Framework o trecho de código ficaria desta maneira:
Connection conn = DataSourceUtils.getConnection(dataSource);
Caso já exista uma transação associada à uma conexão, esta conexção será retornada. Caso contrário, a
invocação deste método disparará a criação de um novo objeto Connection que será, opcionalmente, associado à
uma transação e estará disponível para reuso dentro desta transação. Outra vantagem desta classe apresenta-se no
encapsulamento de qualquer SQLException dentro de uma CannotGetJdbcConnectionException. Esta é uma das
muitas exceções de acesso à dados do Spring Framework, que fornece muitas informações adicionais àquelas obtidas
por meio de uma simples exceção SQLException.
CONTROLE DECLARATIVO DE TRANSAÇÕES
Segundo JOHNSON et AL (2009), o controle de transações declarativas no Spring Framework se dá por
meio do módulo Spring AOP. Embora os códigos de aspectos transacionais sejam intrínsecos ao framework, nem
sempre é necessário entendê-los para fazer o uso efetivo deles.
Abaixo seguem algumas características do controle de transações declarativas com o spring framework:
O controle de transações declarativas do Spring Framework funciona em qualquer ambiente. Pode funcionar
com JDBC, JDO, Hibernate ou outros mecanismos de persistência, apenas com modificações nas
configurações.
O framework habilita ao desenvolvedor a atribuir transações declarativas à qualquer classe.
O framework oferece a possibilidade de criar regras de rollback.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 68/84
O framework oferece a possibilidade de customização do comportamento transacional.
O framework não suporta a propagação de transações para recursos remotos.
O conceito de regras de rollback é importante. Ele habilita ao desenvolvedor especificar quais exceções
deverão causar um rollback automático. Estas configurações não são feitas em código Java, retirando assim, qualquer
dependência dos objetos de negócios da infra-estrutura de controle de transações.
9.
1.1.30Entendendo a implementação das transações declarativas do Spring Framework
JOHNSON et AL (2009) explica que o conceito mais importante do suporte a transações declarativas do
Spring é entender que este suporte é habilitado por meio da orientação à aspectos e que o advice transacional é
dirigido por metadados (neste caso, por XML ou anotações). A combinação da orientação à aspectos com os
metadados transacionais criam um proxy AOP que utiliza um TransactionInterceptor em conjunto com a
implementação apropriada do PlataformTransactionManager para dirigir as transações ao redor dos métodos.
Conceitualmente, este conjunto de classes e ações deve se comportar conforme mostra a ilustração 16.
Ilustração 16:Mecanismo de controle de transações declarativas.
Fonte: JOHNSON et AL (2009)
Consideremos a seguinte interface e sua implementação:
Interface:
package br.fatec.tcc.service;
import br.fatec.tcc.dto.DadosFicticios;
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 69/84
public interface ExemploService {
public DadosFicticios getDados(String nome);
public DadosFicticios getDados(String nome, String sobrenome);
public void insereDados(DadosFicticios novosdados);
public void atualizaDados(DadosFicticios dadosAtualizados);
}
Implementação
package br.fatec.tcc.service.impl;
import br.fatec.tcc.dto.DadosFicticios;
import br.fatec.tcc.service.ExemploService;
public class ExemploBean implements ExemploService {
@Override
public DadosFicticios getDados(String nome) {
throw new UnsupportedOperationException();
}
@Override
public DadosFicticios getDados(String nome, String sobrenome) {
throw new UnsupportedOperationException();
}
@Override
public void insereDados(DadosFicticios novosdados) {
throw new UnsupportedOperationException();
}
@Override
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 70/84
public void atualizaDados(DadosFicticios dadosAtualizados) {
throw new UnsupportedOperationException();
}
}
Assumindo que os dois primeiros métodos da interface ExemploService devem ser executados dentro do
contexto de uma transação com semântica somente leitura e os outros métodos tem que ser executados no contexto
transacional com semantica leitura-escrita. O arquivo de contexto da aplicação (context.xml) deverá conter as
seguintes configurações:
<!-- arquivo 'context.xml' -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-
tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- objeto que se tornará transacional -->
<bean id="exemploService" class="br.fatec.tcc.service.impl.ExemploBean" />
<!-- advice transacional -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- semânticas transacionais... -->
<tx:attributes>
<!-- todos os métodos que começam com 'get' usarão
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 71/84
semântica somente
leitura -->
<tx:method name="get*" read-only="true" />
<!-- outros métodos utilizarão as configurações padrão de
transação -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<!-- assegura que o advice transactional rodará em qualquer execução
de uma operação definida na intercace ExemploService -->
<aop:config>
<aop:pointcut id="operacoesExemploService"
expression="execution(* br.fatec.tcc.service.ExemploService.*(..))" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="operacoesExemploService" />
</aop:config>
<!-- datasource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@127.0.0.1:1521:fatec" />
<property name="username" value="scott" />
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 72/84
<property name="password" value="tiger" />
</bean>
<!-- transaction manager -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- outras definições da aplicação-->
</beans>
Para um melhor entendimento, dividir-se-á em pequenas partes às configurações acima. O objeto que se
tornará transacional está definido no elemento <bean /> com a propriedade “name” igual a “exemploService”. As
semânticas transacionais que pretende-se aplicar estão encapsuladas na definição do elemento <tx:advice />. Pode-se
ler esta definição da seguinte maneira: “todos os métodos iniciando com a palavra ‘get’ deverão ser executados dentro
do contexto de uma transação somente leitura; os demais métodos, deverão ser executados com a semântica
transacional padrão”. O atributo transaction-manager é atribuido com o nome do gerenciador de transações, que irá,
de fato, controlá-las (neste caso, definido no elemento <bean /> com a propriedade name igual a “txManager”).
O elemento <aop:config /> assegura que o advice, definido com nome ‘txAdvice’, execute nos pontos
corretos do programa. Foi criado um pointcut que corresponde à todas as execuções de métodos da interface
ExemploService (‘operacoesExemploService’) e associado ao advice acima citado, por meio de um assessor
(elemento <aop:advisor />). O resultado desta ligação significa que sempre que houver alguma execução de métodos
das classes contidas dentro do escopo do pointcut (neste caso, apenas a interface Exemploservice), o advice será
executado.
1.1.31Desfazendo a transação
JOHNSON et AL (2009) entende que a maneira mais recomendada para indicar à infra-estrutura de
transações do Spring Framework que é necessário desfazer uma transação (rollback) é o lançamento de uma
Exception do código que está executando no contexto da transação. O framework tratará todas as exceções não
tratadas e marcará a transação para ser desfeita.
Todavia, por padrão o framework apenas marcará a transação para ser desfeita quando ocorrer alguma
exceção dos tipos RuntimeException e Error. Porém, a definição de quais exceções além destas poderá marcar a
transação para ser desfeita é configurável. O fragmento do XML de configuração abaixo mostra de que maneira
pode-se indicar uma exceção específica da aplicação para desfazer a transação.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 73/84
<tx:advice id="txAdvice" transaction-manager="txManager" >
<tx:attributes>
<tx:method name="get*" read-only="true"
rollback-for="SemProdutosEmEstoqueException"/>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
Também é possível configurar quando uma aplicação não deverá ser desfeita a partir do lançamento de uma
exceção verificada. No exemplo abaixo, basicamente indica-se ao framework que realize o commit das informações
mesmo que seja lançada uma exceção InstrumentoNaoEncontradoException
<tx:advice id="txAdvice" transaction-manager="txManager" >
<tx:attributes>
<tx:method name="get*" read-only="true"
no-rollback-for="InstrumentoNaoEncontradoException"/>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
1.1.32Configurações do elemento <tx:advice />
Segundo JOHNSON et AL (2009), as configurações padrão da tag <tx:advice /> são:
A propagação é REQUIRED
O nivel de isolamento é o DEFAULT
As transações são de leitura/escrita
O timeout é definido pelo sistema subjacente de transações. Caso não haja nenhum, o timeout não é suportado.
Qualquer exceção do tipo RuntimeException marca a transação para ser desfeita.
Estas configurações poderão ser modificadas; vários dos atributos da tag <tx:method /> estão aninhados nas
tags<tx:advice /> e <tx:attributes/>. Abaixo a tabela detalha os atributos da tag <tx:method />
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 74/84
Atributo Requerido Padrão Descrição
name Sim O nome do(s) método(s) com o qual(ais)os atributos de transação devem serassociados. O caráter curinga (*) podeser usado pode ser usado para associaras configurações mesma transaçãoatributo com uma série de métodos, porexemplo, 'get*', 'handle*', 'on*Event' eassim por diante
propagation Não REQUIRED O comportamento de propagação detransações
isolation Não DEFAULT O nível de isolamento da transação
timeout Não -1 O valor de tempo limite de transação (emsegundos)
read-only Não falso É essa transação somente leitura?
rollback-for Não A(s) exceção(ões) que irá(ão) acionar areversão; separado por vírgulas. Porexemplo:''com.foo.MyBusinessException,ServletException"
no-rollback-for Não A(s) exceção(ões) que não irá(ão)acionar a reversão; separado porvírgulas. Por exemplo:''com.foo.MyBusinessException,ServletException"
Tabela 5: Propriedades da tag <tx:method />Fonte: JOHNSON et AL (2009)
1.1.33Utilizando a anotação @Transactional
JOHNSON et AL (2009) ensina que, além da abordagem baseada em XML para controle de transações
declarativas, o Spring também suporta uma abordagem baseada em anotações. Declarar as semânticas de transação
diretamente no código fonte coloca as configurações mais próximas dos códigos afetados, porém não significa um
acoplamento indevido. A facilidade de uso da anotação @Transacional será ilustrada no trech de código abaixo:
package br.fatec.tcc.service;
import br.fatec.tcc.dto.DadosFicticios;
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 75/84
@Transacional
public interface ExemploService {
public DadosFicticios getDados(String nome);
public DadosFicticios getDados(String nome, String sobrenome);
public void insereDados(DadosFicticios novosdados);
public void atualizaDados(DadosFicticios dadosAtualizados);
}
Para que esta anotação seja habilitada e utilizada pelo framework, no arquivo XML de contexto da aplicação
deverá ser adicionada apenas uma linha, conforme exemplo abaixo:
<!-- arquivo 'context.xml' -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-
tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- objeto que se tornará transacional -->
<bean id="exemploService"
class="br.fatec.tcc.service.impl.ExemploBean" />
<!-- habilita o controle transacional via anotações -->
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 76/84
<tx:annotation-driven transaction-manager="txManager" />
<!-- datasource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@127.0.0.1:1521:fatec" />
<property name="username" value="scott" />
<property name="password" value="tiger" />
</bean>
<!-- transaction manager -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- outras definições da aplicação -->
</beans>
A anotação @Transacional pode ser colocada antes da declaração de uma interface, dos métodos de uma
interface, da declaração de uma classe ou na declaração de um método público. De qualquer maneira, deve-se notar
que apenas a presença da anotação na interface, classe ou métodos não é o suficiente para que o comportamento
transacional aconteça. É necessário que no arquivo de contexto contenha o elemento <tx:annotation-driven />.
1.1.34Configurações da anotação @Transacional
Para JOHNSON et AL (2009), a anotação @Transacional é um metadado que especifica que uma classe,
interface ou método devem ter uma determinada semântica transacional. Os valores padão são:
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 77/84
A propagação é PROPAGATION_REQUIRED
O isolamento é ISOLAMENT_DEFAULT
A transação é de leitura/escrita
O timeout é definido pelo sistema subjacente de transações. Caso não haja nenhum, o timeout não é suportado.
Qualquer exceção do tipo RuntimeException marca a transação para ser desfeita.
Estas configurações poderão ser alteradas. As propriedades da anotação @Transacional estão sumarizadas
na tabela 6:
Propriedade Tipo Descrição
propagation enum: Propagation configuração opcional depropagação
isolation enum: Isolation nível de isolamentoopcional
readOnly boolean leitura / escrita versussomente leitura
timeout int (em segundos) tempo limite detransação
rollbackFor um array de objetos declasse, que devem serderivadas de Throwable
uma matriz opcional declasses de exceção quedeve causar reversão
rollbackForClassname uma série de nomes declasses. Classes devemser derivadas deThrowable
uma matriz opcional denomes de classes deexceção que deve fazerrollback
noRollbackFor um array de objetos declasse, que devem serderivadas de Throwable
uma matriz opcional declasses de exceção quenão deve provocarreversão.
noRollbackForClassname
uma série de nomes declasses. Classes devemser derivadas deThrowable
uma matriz opcional denomes de classes deexceção que não deveprovocar reversão
Tabela 5: Propriedades da tag <tx:method />Fonte: JOHNSON et AL (2009)
CONTROLE PROGRAMÁTICO DE TRANSAÇÕES
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 78/84
Segundo JOHNSON et AL (2009) , o Spring Framework oferece duas maneiras de controlar a transação
programáticamente:
Usando o TransactionTemplate
Usando uma das implementações de PlataformTransactionManager diretamente.
10.
1.1.35Usando TransactionTemplate
Para JOHNSON et AL (2009), o TransactionTemplate adota a mesma abordagem dos outros padrões
Spring, como o JdbcTemplate. Ele usa uma abordagem de callback para livrar o código da aplicação dos códigos
repetitivos de aquisição e liberação dos recursos transacionais, o que resulta em um código mais intuitivo e que
contém apenas o que o desenvolvedor deve fazer.
O código que deve ser executado em um contexto transacional usará explicitamente a classe
TransactionTemplate. O desenvolvedor deverá escrever uma implementação da interface TransactionCallback
(típicamente uma classe aninhada anônima), a qual conterá o código que deverá ser executado em contexto
transacional. Esta implementação customizada da interface TransactionCallback será passada como parâmetro para o
método execute(...), da classe TransactionTemplate, conforme trecho de código abaixo;
public class ExemploBean implements ExemploService {
// unica instância do TransactionTemplate, compartilhada entre todos // os métodos desta
instância de ExemploBean
private final TransactionTemplate transactionTemplate;
// usar a injeção por constructor para injetar o objeto
// transactionManager
public ExemploBean(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager,
"O argumento 'transactionManager' não pode ser null.");
this.transactionTemplate = new
TransactionTemplate(transactionManager);
}
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 79/84
public Object atualzaDados() {
return transactionTemplate.execute(new TransactionCallback() {
// código executado no contexto transacional
public Object doInTransaction(TransactionStatus status){
atualiza();
return resultadoAtualizacao();
}
});
}
}
Caso o código não tenha um retorno, ele deverá ser colocado dentro de uma implementação da interface
TransactionCallbackWithoutResult. Caso seja necessário, o código dentro desta implementação também poderá
marcar a transação para ser desfeita, conforme ilustrado pelo código abaixo:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus status) {
try {
atualiza();
resultadoAtualizacao();
} catch (Exception e) {
status.setRollbackOnly();
}
}
});
1.1.35.1Especificando as configurações da transação
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 80/84
Como nos ensina JOHNSON et AL (2009), as configurações da transação, tais como isolamento, modo de
propagação, tempo máximo de transação e assim por diante pode ser estabelecido tanto programáticamente quanto
por meio de configurações realizadas em arquivos de metadados. O código abaixo demonstra como realizar estes
ajustes programáticamente.
public ExemploBean(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager,
"O argumento 'transactionManager' não pode ser null.");
this.transactionTemplate = new
TransactionTemplate(transactionManager);
// as configurações da transação deverão ser
// explicitadas aqui, caso necessário
this.transactionTemplate.setIsolationLevel(
TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30 seconds
}
O fragment de arquivo XML de configuração do Spring abaixo mostra como configurar as propriedades do
TransactionTemplate por metadata. O bean ‘transactionTemplateCompartilhado’ poderá ser injetado em quantos
beans for necessário.
<bean id="sharedTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="isolationLevelName"
value="ISOLATION_READ_UNCOMMITTED" />
<property name="timeout" value="30" />
</bean>
1.1.36Usando PlataformTransactionManager
Segundo JOHNSON et AL (2009), o uso da interface PlataformTransactionManager permite ao
desenvolvedor controlar a transação diretamente em seu código fonte. Para tal, basta atrelar a instância do
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 81/84
gerenciador de transações ao seu bean via referência por metadata e então, utilizar as classes TransactionDefinition e
TransactionStatus para iniciar, finalizar com sucesso (commit) ou desfazer (rollback) a transação.
Código fonte:
public class ExemploBean implements ExemploService {
// unica instância do TransactionTemplate, compartilhada entre todos
// os métodos desta instância de ExemploBean
private final PlatformTransactionManager txnManager;
// usar a injeção por constructor para injetar o objeto
// transactionManager
public ExemploBean(PlatformTransactionManager transactionManager) {
this.txnManager = transactionManager;
}
public Object atualzaDados() {
DefaultTransactionDefinition def = new
DefaultTransactionDefinition();
// a unica maneira de definir o nome de uma transação é
// programaticamente.
def.setName("SomeTxName");
def.setPropagationBehavior(
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 82/84
TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = this.txnManager.getTransaction(def);
try {
// logica de negócios
} catch (MyException ex) {
this.txnManager.rollback(status);
throw ex;
}
this.txnManager.commit(status);
}
}
Arquivo de configuração:
<bean id="exemploService" class="br.fatec.tcc.service.impl.ExemploBean">
<property name="txnManager" ref="txManager" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 83/84
conclusão
Pode-se concluir por meio deste trabalho que as transações tem um papel muito importante nas aplicações,
tanto nas de pequeno e médio porte quanto nas de grande porte. Ela é uma das maiores responsáveis pela integridade
dos dados manipulados pela aplicação e, com a manutenção de suas propriedades ACID, evita a corrupção destes.
Foi possível abordar minuciosamente todas as particularidades de uma transação e as melhores maneiras de
se implementar o controle de transações, por meio de padrões de projetos existentes no mercado.
Conclui-se também que o Spring é um framework versátil e leve, pois pode ser utilizado tanto em aplicações
de pequeno porte como em aplicações corporativas com alta concorrência entre recursos, pois suporta a aplicação da
maioria dos requisitos funcionais e não funcionais necessários para a estabilização de uma aplicação em abimente
produtivo (por meio de de módulos como o Spring AOP, Spring Web, Spring ORM, Spring DAO, entre outros).
Uma de suas principais características é o suporte ao controle de transações, que tem como principal objetivo reduzir
a complexidade da sua implementação e manipular de maneira apropriada a utilização de recursos relacionados à este
controle. Desta maneira, o uso deste framework para o controle de transação traz muito pouco impacto no
desenvolvimento do código fonte (evitando assim que o código fique altamente acoplado com a infra-estrutura
necessária para tal gerenciamento), permitindo que o desenvolvedor escreva um código mais intuitivo e voltado ás
necessidades de negócio da aplicação.
6/21/13 CENTRO PAULA SOUZA
dc299.4shared.com/doc/OX5FbF8I/preview.html 84/84
REFERÊNCIAS
http://martinfowler.com/articles/injection.html
Pro spring
Spring in action
Spring reference
Susan Cheung & Vlada Matena JTA Specification April 29, 1999
http://download.oracle.com/auth/otn-pub/jcp/7286-jta-1.0.1-spec-oth-JSpec/jta-spec1_0_1.pdf?e=1319304537&h=a891ba070b2198a3ec48dc6fcc7e9f35 22/10/2011
Um autor
GOMES, M.L. A sexualidade nos adolescentes . 2. ed. São Paulo: Desenvolvimento,1998.
GOMES, M.L.; PÁDUA, F.S.M. A sexualidade nos adolescentes. 2. ed. São Paulo: Desenvolvimento,1998.
COSTA, C.R. et al. A sexualidade nos adolescentes. 2. ed. São Paulo: Desenvolvimento,1998.
Organizador/coordenador
MARTINS, J.A. A pesquisa qualitativa. In. Fazenda, I (coord) A metodologia da pesquisa. 3.ed. São Paulo: Cortez,1992,cap. 4, p. 47-58.
Autoria desconhecida
DIAGNÓSTICO do setor industrial brasileiro. São Paulo: Câmara Brasileira do Livro,1995. disponível em<www.fundep.com,.br) acesso em10 de agos 2009.