transa es e concorr ncia l.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Transações e concorrência PowerPoint Presentation
Download Presentation
Transações e concorrência

Loading in 2 Seconds...

play fullscreen
1 / 37

Transações e concorrência - PowerPoint PPT Presentation


  • 196 Views
  • Uploaded on

Transações e concorrência. Jobson Ronan {jrjs@cin.ufpe.br}. O que é uma transação?. Uma transação é uma unidade de trabalho que não pode ser dividida. É uma operação atômica. Há dois níveis de granularidade em aplicações corporativas Transações de banco de dados

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Transações e concorrência' - kellan


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
transa es e concorr ncia

Transações e concorrência

Jobson Ronan {jrjs@cin.ufpe.br}

o que uma transa o
O que é uma transação?
  • Uma transação é uma unidade de trabalho que não pode ser dividida. É uma operação atômica.
  • Há dois níveis de granularidade em aplicações corporativas
    • Transações de banco de dados
    • Transações longas (de aplicação): envolvem várias transações de banco de dados
  • Uma transação ou termina com sucesso (commit) ou desfaz todo o processo (rollback)
  • A maior parte da complexidade de se lidar com transações é ocultada pelo sistema (Hibernate, servidor de aplicações, banco de dados)
    • O trabalho consiste, geralmente, em demarcar o início e fim das transações
transa es em servidores
Transações em servidores
  • Demarcar transações em uma aplicação JDBC é fácil. Basta configurar a Conexão conncom da seguinte forma
    • conn.setAutoCommit(false);
  • Os statements executados serão acumulados e só serão tornados definitivos no banco após um conn.commit()
  • Ou serão desfeitos caso ocorra um conn.rollback()
  • Em servidores de aplicação, ou quando é preciso realizar transações entre vários bancos, é preciso usar o protocolo Two-phase commit, que gerencia o processo
    • Para isto existe a API JTA e a classe UserTransaction que encapsula transações distribuídas
tratamento de transa es em hibernate

Executado dentro da transação

Tratamento de transações em Hibernate

Session session = sessions.openSession();

Transaction tx = null;

try {

tx = session.beginTransaction();

concludeAuction();

tx.commit();

} catch (Exception e) {

if (tx != null) {

try {

tx.rollback();

} catch (HibernateException he) {

//log he and rethrow e

}

}

throw e;

} finally {

try {

session.close();

} catch (HibernateException he) { throw he; }

}

transa es no hibernate
Transações no Hibernate
  • O Hibernate encapsula o sistema de transações do banco (JDBC) ou servidor (ambiente gerenciado) usado
  • A transação começa na Session com uma chamada para session.beginTransaction()
    • Em um ambiente não gerenciado, isto inicia uma transação JDBC na conexão.
    • Em um ambiente gerenciado, inicia uma transação JTA ou une-se à transação existente.
  • Commit e rollback. Em uma transação Transaction tx:
    • tx.commit() sincroniza o estado da sessão com o banco de dados.
    • tx.rollback() ou desfaz imediatamente a transação ou marca a transação para rollback.
  • É importante fechar a sessão em um bloco finally para garantir que a conexão JDBC será liberada e retornada ao pool de conexões.
flushing descarregando
Flushing (descarregando)
  • O objeto Session implementa "transparent write behind“
    • Mudanças ao modelo de domínio não são imediatamente persistidas no banco (para reduzir acesso ao banco)
    • Gravação/sincronização transparente dos dados no final da transação.
  • Flushing é a sincronização da camada de objetos com a camada de dados. Ocorre quando
    • Uma transação é cometida
    • Às vezes, antes que uma query é executada
    • Quando a aplicação chama explicitamente session.flush()
isolamento
Isolamento
  • Bancos de dados e sistemas transacionais tentam garantir isolamento entre transações
    • Isolamento completo é uma utopia.
    • É muito caro em termos de escalabilidade da aplicação.
  • Bancos de dados fornecem vários graus de flexibilização de isolamento
    • Variam de isolamento completo a isolamento praticamente inexistente (neste caso, cabe à aplicação lidar com os conflitos)
  • Para a maior parte das aplicações, isolamento incompleto de uma transação é aceitável
problemas de isolamento
Problemas de isolamento
  • O padrão ANSI SQL define os níveis de isolamento de transações em termos de fenômenos que podem ou não serem permitidos. Os fenômenos são:
  • Update perdido (lost update)
    • Duas transações ambas atualizam um registro e a segunda transação aborta, fazendo com que as duas mudanças sejam perdidas.
    • As transações concorrentes não têm isolamento algum.
  • Leitura suja (dirty read)
    • Uma transação lê mudanças feitas por transação que ainda não cometeu os dados.
    • Essa mudança pode ser desfeita em um rollback.
problemas de isolamento9
Problemas de isolamento
  • Leitura não-repetível (unrepeatable read)
    • Uma transação lê um registro duas vezes e obtém um estado diferente em cada leitura.
    • Outra transação pode ter gravado dados e cometido mudanças entre as duas leituras
  • Leitura fantasma (phantom read)
    • Uma transação executa uma consulta duas vezes, e o segundo resultado inclui registros que não estavam na primeira consulta.
    • Novos registros foram inseridos por outra transação entre as consultas.
n veis de isolamento jdbc
Níveis de isolamento JDBC
  • JTA usa esses mesmos níveis de isolamento
  • Read uncommitted
    • Permite dirty reads mas não updates perdidos.
    • Uma transação não pode gravar em um registro se outra transação não cometida já gravou dados nele.
    • Este nível de isolamento pode ser implementado com locks de gravação exclusiva.
  • Read committed
    • Permite unrepeatable reads mas não dirty reads.
    • Transação de gravação não cometida impede que outras transações acessem registro.
    • Transações de leitura não bloqueiam o sistema.
n veis de isolamento jdbc11
Níveis de isolamento JDBC
  • Repeatable read
    • Não permite unrepeatable reads nem dirty reads.
    • Podem ocorrer phantom reads.
    • Transações de leitura bloqueiam transações de gravação (mas não outras transações de leitura) e transações de gravação bloqueiam todas as outras.
  • Serializable
    • Fornece o isolamento mais rigoroso.
    • Emula execução em série de transações (em vez de concorrentemente).
qual n vel de isolamento
Qual nível de isolamento?
  • A escolha do nível de isolamento depende do cenário onde a aplicação executa.
    • Não existe uma regra que sirva para todas as situações.
  • Qual um nível razoável de isolamento para aplicações típicas?
    • Isolamento excessivo geralmente não é aceitável, devido ao alto custo quanto à escalabilidade (crítica nas aplicações típicas do Hibernate), portanto o isolamento serializable não deve ser usado
    • O isolamento read uncommitted é perigoso, e não deve ser usado se houver opções melhores no banco
    • Suporte a versioning (travas otimistas) e uso do cache de segundo nível (por classe) do Hibernate já alcançam a maior parte dos benefícios de um isolamento do tipo repeatable read, usando read committed.
  • Portanto, read committed é uma boa opção com o Hibernate.
como mudar o n vel de isolamento default
Como mudar o nível de isolamento default?
  • É preciso definir uma propriedade no hibernate.properties ou hibernate.cfg.xml. Use:

hibernate.connection.isolation=numero

onde número é 1, 2, 4 ou 8. Exemplo:

hibernate.connection.isolation = 4

  • O número refere-se a um dos quatro níveis:
    • 1—Read uncommitted isolation
    • 2—Read committed isolation
    • 4—Repeatable read isolation
    • 8—Serializable isolation
  • Só é possível fazer esse controle em ambientes não gerenciados
    • Servidores de aplicação têm configuração própria.
estrat gias de isolamento locais
Estratégias de isolamento locais
  • Nível de isolamento global afeta todas as conexões
    • Read committed é um bom isolamento default para aplicações Hibernate
  • Mas pode ser desejável utilizar travas mais rigorosas para transações específicas
  • Existem duas estratégias
    • Travas pessimistas (evita colisões entre transações bloqueando totalmente o acesso de outras transações)
    • Travas otimistas (onde o sistema flexibiliza o isolamento mas lida com eventuais colisões)
travas pessimistas
Travas pessimistas
  • Uma trava pessimista é adquirida quando dados são lidos e mantidos isolados de outras transações até que a sua transação complete.
    • Em modo read-committed, o banco de dados nunca adquire travas pessimistas a não ser que sejam requisitadas explicitamente
  • Classe LockMode
    • Permite a solicitação de uma trava pessimista em um objeto
  • Considere a seguinte transação

Transaction tx = session.beginTransaction(); Category cat = (Category) session.get(Category.class, catId); cat.setName("New Name"); tx.commit();

  • Uma trava pessimista pode ser obtida da seguinte forma:

Transaction tx = session.beginTransaction(); Category cat = (Category) session.get(Category.class, catId, LockMode.UPGRADE); cat.setName("New Name"); tx.commit();

controle de lockmode
Controle de LockMode
  • Os modos suportados para LockMode são:
    • NONE - Só vai ao banco se o objeto não estiver no cache. Default em load() e get()
    • READ - Ignora cache e faz verificação de versão para assegurar-se que o objeto na memória é o mesmo que está no banco.
    • UPDGRADE - Ignora cache, faz verificação de versão (se aplicável) e obtém trava pessimista (se suportada).
    • UPDGRADE_NOWAIT- Mesmo que UPGRADE, mas desabilita a espera por liberação de travas, e provoca exceção de locking se a trava não puder ser obtida.
    • WRITE- Obtida automaticamente quando Hibernate grava em um registro na transação atual
controle de lockmode17
Controle de LockMode
  • Sincronização de objeto desligado se registro não foi alterado por outra transação.

Item item = ... ;

Bid bid = new Bid();

item.addBid(bid);

...

Transaction tx = session.beginTransaction();

session.lock(item, LockMode.READ);

tx.commit();

Caching é considerada uma solução melhor que travas pessimistas.

Evite usar LockMode explícito a não ser que realmente seja necessário.

transa es longas de aplica o
Transações longas (de aplicação)
  • Processos de negócio
    • Podem ser consideradas uma única unidade de trabalho do ponto de vista de um usuário.
    • Transação de baixa granularidade.
    • Uma noção mais abrangente da unidade de trabalho.
  • Exemplo de cenário típico
    • Dados são recuperados e mostrados na tela em uma primeira transação do banco
    • O usuário tem uma oportunidade de visualizar e modificar os dados, fora de uma transação
    • As modificações são feitas persistentes em uma segunda transação de banco de dados
como lidar com as colis es
Como lidar com as colisões?
  • Três estratégias
    • Último commit ganha - os dois updates funcionam, mas o segundo sobrescreve as alterações do primeiro. Nenhuma mensagem de erro é mostrada.
    • Primeiro commit ganha - a primeira modificação é feita persistente, e o usuário que envia a segunda recebe uma mensagem de erro. Optimistic locking.
    • Mesclar updates conflitantes - A primeira modificação é persistida, e a segunda pode ser aplicada seletivamente pelo usuário.
  • A primeira opção é problemática para várias aplicações
    • É importante que o usuário pelo menos saiba do erro
    • Acontece por default.
  • Hibernate ajuda a implementar as outras duas estratégias usando controle de versões e travas otimistas.
uso de managed versioning controle de vers o
Uso de managed versioning (controle de versão)
  • Depende de que um número seja incrementado sempre que um objeto é modificado.

public class Comment {

...

private int version; ...

void setVersion(int version) {this.version = version;}

int getVersion() {return version;}

}

  • No arquivo de mapeamento, <version> vem logo depois de <id>

<class name="Comment" table="COMMENTS">

<id ...

<version name="version" column="VERSION"/>

...

</class>

  • O número de versão é só um contador. Não tem outra utilidade.
    • Uma alternativa é usar um timestamp
timestamp
Timestamp
  • Alternativa ao <version>. Exemplo:

public class Comment { ...

private Date lastUpdated;

void setLastUpdated(Date lastUpdated) {

this.lastUpdated = lastUpdated;

}

public Date getLastUpdated() {return lastUpdated;}

}

  • Mapeamento

<class name="Comment" table="COMMENTS">

<id ...../>

<timestamp name="lastUpdated" column="LAST_UPDATED"/>

...

</class>

  • Em tese, um timestamp é menos seguro pois duas transações concorrentes poderiam tentar load e update no mesmo milisegundo.
travas otimistas
Travas otimistas
  • O Hibernate controla a inicialização e gerenciamento de <version> e <timestamp> automaticamente.
    • Esses recursos permitem o eficiente gerenciamento de colisões que implementam a estratégia de trava otimista.
    • StaleObjectStateException é lançado em caso de inconsistência
  • Otimistas versus Pessimistas
    • Enfoque pessimista assume que serão constantes os conflitos e o ideal é bloquear completamente o acesso. Não ultrapassa os limites de uma sessão
    • Enfoque otimista assume que conflitos serão raros e quando eles acontecerem, é possível lidar com eles. Garante maior escalabilidade e suporta transações longas.
granularidade de uma sess o
Granularidade de uma Sessão
  • Session-per-request
    • Uma sessão tem a mesma granularidade de uma transação
  • Session-per-request-with-detached-objects
    • Objetos são modificados entre duas sessões
    • Uma transação por sessão
    • Objetos desligados
  • Session-per-application-transaction
    • Sessão longa
    • Objetos mantêm-se persistentes
cache
Cache
  • O cache é uma cópia local dos dados.
    • Fica entre sua aplicação e o banco de dados.
  • O cache evita acesso ao banco sempre que
    • A aplicação faz uma pesquisa por chave primária ou
    • A camada de persistência resolve uma associação usando estratégia lazy
  • Podem ser classificados quanto ao escopo:
    • Escopo de transação - cada unidade de trabalho tem seu próprio cache; vale enquanto a transação está rodando.
    • Escopo de processo - o cache é compartilhado entre transações (há implicações quanto ao isolamento)
    • Escopo de cluster - compartilhado entre processos na mesma máquina ou entre múltiplas máquinas de um cluster.
cache no hibernate
Cache no Hibernate
  • Dois níveis
    • Primeiro nível tem escopo de transação.
    • Segundo nível é opcional e tem nível de processo ou cluster.
  • O primeiro nível é a Session.
    • Uma session ou tem a duração de uma transação de banco de dados ou de uma transação de aplicação longa.
    • Não pode ser desligada.
    • Garante identidade do objeto dentro da transação.
  • O segundo nível é cache de estado (valores; não instâncias)
    • É opcional
    • Pode ser configurado por classe ou por associação.
primeiro e segundo cache
Primeiro e segundo cache
  • Cache de primeiro nível
    • Automático (Session)
    • Usado sempre que se passa um objeto para save(), update(), saveOrUpdate() ou quando ele é requisitado com load(), find(), list(), iterate(), ou filter()
    • Garante que quando uma aplicação requisita o mesmo objeto persistente duas vezes numa sessão, ela recebe de volta a mesma instância.
  • Cache de segundo nível
    • Instâncias persistentes são desmontadas (é como serialização, mas o algoritmo é mais rápido).
    • Requer conhecimento sobre os dados para uso eficiente (não é automático – as classes são mapeadas ao cache uma por uma)
    • Se dados são mais freqüentemente atualizados que lidos, não habilite o cache de segundo nível
    • Requer configuração fina em gerente de cache para melhor performance
resumo tags de mapeamento
Resumo: tags de mapeamento
  • <version>
    • Usado em implementação de transações longas, para sinalizar que uma tabela/objeto está sendo alterada
  • <cache>
    • Usado para definir política de cache de segundo nível
propriedades transa o e cache
hibernate.cache.provider_class=nome.da.Classe

Usa um cache provider próprio em substituição ao nativo usado pelo Hibernate (implementação de org.hibernate.cache.CacheProvider)

hibernate.transaction.factory_class=nome.da.Classe

Para definir um gerente de transações próprio, ou

org.hibernate.transaction.<nome> para usar uma implementação disponível, onde <nome> pode ser

JBossTransactionManagerLookup

WeblogicTransactionManagerLookup

WebSphereTransactionManagerLookup

OrionTransactionManagerLookup

ResinTransactionManagerLookup

JOTMTransactionManagerLookup

JOnASTransactionManagerLookup

...

Propriedades: transação e cache

Propriedades para hibernate.properties ou hibernate.cfg.xml

boas pr ticas
Boas Práticas
  • Usar sempre o padrão facade
  • ...mas como englobar várias operações a a vários DAOs em uma transação?
classe utilit ria simples
Classe utilitária simples

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static {

try {

Configuration cfg = new Configuration();

sessionFactory = cfg.configure().buildSessionFactory();

} catch (Throwable ex) {

ex.printStackTrace(System.out);

throw new ExceptionInInitializerError(ex);

}

}

//...

}

classe utilit ria simples31
Classe utilitária simples

//..

private static Session session;

public static Session getSession() {

try {

if (session == null || !session.isOpen()) {

SessionFactory factory = getSessionFactory();

session = factory.openSession();

}

return session;

} catch (Exception e) {

throw new RuntimeException(e);

}

}

//...

classe utilit ria simples32
Classe utilitária simples
  • Suporte transacional

//..

private static Transaction transaction;

public static void beginTransaction() {

transaction = getSession().beginTransaction();

}

public static void commit() {

if (transaction != null)

transaction.commit();

}

public static void rollback() {

if (transaction != null)

transaction.rollback();

}

//...

usando
Usando
  • Todo DAO, quando precisar de uma Sessão, irá obte-la através do getSession()
    • Para que vários DAOs obtenham a mesma sessão, basta não fecha-la
  • A fachada pode gerencar a transação com os metodos begin, commit e rollback
    • Os DAOs não gerencia, mais as transações
  • ...Mas se a houver acesso concorrente
classe utilit ria com suporte a concorrencia
Classe utilitária com suporte a concorrencia

//..

private static final ThreadLocal<Session> localSession =

new ThreadLocal<Session>();

public static Session getSession() {

try {

Session session = localSession.get();

if (session == null || !session.isOpen()) {

SessionFactory factory = getSessionFactory();

session = factory.openSession();

localSession.set(session);

}

return session;

} catch (Exception e) {

throw new RuntimeException(e);

}

}

//...

classe utilit ria com suporte a concorrencia35
Classe utilitária com suporte a concorrencia

//..

private static final ThreadLocal<Transaction> localTx =

new ThreadLocal<Transaction>();

public staticvoid beginTransaction() {

localTx.set(getSession().beginTransaction());

}

public static void commit() {

if (localTx.get() != null)

localTx.get().commit();

}

public static void rollback() {

if (localTx.get() != null)

localTx.get().rollback();

}

//...

exerc cio
Exercício
  • Criar o modelo de Objetos analisando o schema do banco legado

script.sql

  • Criar criar DAOs e fachada para a aplicação
  • Criar methodos de negício para
    • Realizar uma reserva
    • Agendar uma reserva
    • Cancelar uma reserva
transa es e concorr ncia37

Transações e concorrência

Jobson Ronan {jrjs@cin.ufpe.br}