Visão geral
O gerenciamento da transação é crucial para aplicativos corporativos e pode garantir a consistência dos dados, mesmo que ocorram situações anormais.
A Spring Framework fornece uma abstração consistente para o gerenciamento de transações, com suas características da seguinte maneira:
Forneça modelos de programação consistentes para diferentes APIs de transação, como JTA (Java Transaction API), JDBC, Hibernate, JPA (Java Persistence API e JDO (Java Data Objects)
Suporta o gerenciamento de transações declarativas, especialmente o gerenciamento de transações declarativas com base em anotações, o que é simples e fácil de usar
Fornece uma API mais simples de gerenciamento de transações de programação do que outras APIs de transação, como o JTA
Integração perfeita com abstração de acesso aos dados da primavera
Método de gerenciamento de transações
A primavera suporta dois métodos: gerenciamento de transações programáticas e gerenciamento de transações declarativas.
O gerenciamento de transações programáticas usa o transactionTemplate ou usa diretamente o plataforma de plataforma subjacente. Para gerenciamento de transações programáticas, o Spring recomenda o uso do transactionTemplate.
O gerenciamento de transações declarativo é construído na AOP. Sua essência é interceptar o método antes e depois e criar ou adicionar uma transação antes do início do método de destino. Depois de executar o método de destino, a transação é enviada ou revertida de acordo com a situação de execução. A maior vantagem das transações declarativas é que elas não precisam gerenciar programaticamente as transações, portanto, não há necessidade de dopante o código de gerenciamento de transações no código lógico de negócios. Basta fazer declarações de regras de transação relevantes no arquivo de configuração (ou através da anotação @Transactional) e você pode aplicar regras de transação à lógica de negócios.
Obviamente, o gerenciamento de transações declarativas é melhor que o gerenciamento de transações programáticas, que é exatamente o método de desenvolvimento não invasivo defendido pela primavera. O gerenciamento de transações declarativas mantém o código dos negócios livres de contaminação. Um objeto POJO normal pode obter suporte completo à transação adicionando anotações. Comparado com as transações de programação, a única desvantagem das transações declarativas é que a melhor granularidade deste último só pode atuar no nível do método e não pode ser alcançada como uma transação programática pode atuar no nível do bloco de código. No entanto, mesmo com esse requisito, existem muitas soluções alternativas, como os blocos de código que exigem gerenciamento de transações podem ser processados independentemente, etc.
Existem também dois métodos comumente usados para gerenciamento de transações declarativas. Um é o arquivo de configuração XML com base nos namespaces TX e AOP, e o outro é baseado na anotação @Transaction. Obviamente, o método baseado em anotação é mais simples e mais fácil de usar e mais refrescante.
Commits Automatic (AutoCommit) e se devem enviar automaticamente quando a conexão é fechada
Envio automático
Por padrão, o banco de dados está no modo de envio automático. Cada declaração está em uma transação separada. Quando a execução desta declaração é concluída, se a execução for bem -sucedida, a transação será implicitamente enviada.
Se a execução falhar, a transação será implicitamente revertida.
Para o gerenciamento normal de transações, um conjunto de operações relacionadas está em uma transação; portanto, o modo de comprometimento automático do banco de dados deve ser desligado. No entanto, não precisamos nos preocupar com isso, a primavera definirá o recurso de comprometimento automático da conexão subjacente ao FALSE.
org/springframework/jdbc/dataSource/DataSourCetransactionManager.java
// Mude para o comprometimento manual, se necessário. Isso é muito caro em alguns drivers JDBC, //, então não queremos fazê -lo desnecessariamente (por exemplo, se temos explicitamente // configuramos o pool de conexão para defini -lo) .If (Con.getautocommit ()) {txObject.setMustrestoreAutocommit (True); if (Logger.isdebugenabled ()) {Logger.debug ("Comunda de JDBC Connection [" + con + "] para Commit Manual"); } Con.SetAutocomit (false);}Alguns pools de conexão de dados fornecem configurações para desativar os comissões de transações automáticas, que são melhores para desligar ao configurar o pool de conexões. No entanto, o C3P0 não fornece esse recurso e só pode confiar na mola para defini -lo.
Como a especificação JDBC estipula que, quando o objeto de conexão é estabelecido, ele deve estar no modo de confirmação automático, que é o valor padrão entre os DBMs, e o comprometimento automático deve ser explicitamente desligado, se necessário. O C3P0 cumpre esta especificação e permite que o código do cliente defina explicitamente o modo de envio necessário.
Se deve enviar automaticamente quando a conexão é fechada
Quando uma conexão é fechada, o que deve ser tratado se houver uma transação não comprometida? A especificação JDBC não menciona que a política padrão do C3P0 é reverter quaisquer transações não comprometidas. Esta é a estratégia certa, mas não há acordo entre os provedores de motoristas da JDBC sobre esse assunto.
A propriedade AutocomMitonClose do C3P0 é falsa por padrão, portanto, não há necessidade de não movê -lo. Ou você pode definir explicitamente essa propriedade como falsa, o que será mais claro.
Configuração de gerenciamento de transações declarativas baseadas em anotação
spring-servlet.xml
<!-Suporte à transação-> <!-plataformTransactionMnager-> <bean id = "txManager"> <propriedade name = "DataSource" ref = "DataSource" /> </sien> <!-Ativar suporte à anotação da transação-> <TX: Anotação transação-manager-manager = "txman
Adicione também namespace TX em Spring-Servlet.xml
... xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalocation = "... http: http: //schema/aop" xsi: schemalocation = "... http: http: //schema/aop" xsi: schemalocation = "... http: http: //schema/aop" xsi: schemalocation = "... http: http :/schema/aop" xsi: schemalocation = "... ... http://www.springframework.org/schema/tx/spring-tx.xsd ...
O Mybatis participa automaticamente do gerenciamento de transações de primavera sem configuração adicional. Enquanto a fonte de dados referenciada por org.mybatis.spring.sqlSessionFactoryBean for consistente com a fonte de dados referenciada pelo DataSourCetransactionManager, caso contrário, o gerenciamento de transações não funcionará.
Além disso, você precisa fazer o download do pacote de dependência AOPALLIANCE.JAR e colocá-lo no diretório Web-Inf/Lib. Caso contrário, uma exceção será relatada quando a primavera for inicializada
java.lang.noclassDeffoundError: org/aoPalleionce/intercept/MethodInterceptor
Recursos de transação de primavera
Todas as classes de política de gerenciamento de transações na primavera são herdadas de org.springframework.transaction.platformtransactionManager Interface
Public Interface PlatformTransactionManager {transactionStatus getTransaction (Definição da Definição de Transaction) lança transactionException; Void Commit (status transactionStatus) lança transactionException; Rollback void (status transactionStatus) lança transactionException;}A interface transactionDefinition define as seguintes características:
Nível de isolamento da transação
O nível de isolamento refere -se ao grau de isolamento entre várias transações simultâneas. Cinco constantes representando os níveis de isolamento são definidas na interface transactionDefinition:
TransactionDefinition.isolation_default: Este é o valor padrão, indicando o nível de isolamento padrão usado para o banco de dados subjacente. Para a maioria dos bancos de dados, esse valor geralmente é transactionDefinition.isolation_read_Commited.
TransactionDefinition.isolation_read_uncommited: Este nível de isolamento indica que uma transação pode ler dados modificados por outra transação, mas ainda não foi cometido. Esse nível não impede a leitura suja, a leitura repetitiva e a leitura fantasma; portanto, esse nível de isolamento raramente é usado. Por exemplo, o PostgreSQL não tem esse nível.
TransactionDefinition.isolation_read_Commitd: Este nível de isolamento significa que uma transação pode ler apenas dados que foram cometidos por outra transação. Esse nível impede a leitura suja, que também é o valor recomendado na maioria dos casos.
TransactionDefinition.isolation_repeatable_read: Este nível de isolamento indica que uma transação pode executar uma consulta várias vezes ao longo do processo, e os registros retornados são os mesmos a cada vez. Este nível impede leituras sujas e não repetíveis.
TransactionDefinition.isolation_serializable: Todas as transações são executadas uma a uma em sequência, de modo que não há possibilidade de interferência entre transações, ou seja, esse nível pode evitar leitura suja, leitura não repetível e leitura fantasma. Mas isso afetará seriamente o desempenho do programa. Esse nível geralmente não é usado.
Comportamento de comunicação da transação
O chamado comportamento de propagação da transação refere-se a isso, se um contexto de transação já existir antes do início da transação atual, existem várias opções que podem especificar o comportamento de execução de um método transacional. A definição de transação de definição inclui as seguintes constantes que representam o comportamento de propagação:
TransactionDefinition.propagation_required: Se uma transação estiver presente atualmente, participe da transação; Se atualmente não houver transação, crie uma nova transação. Este é o valor padrão.
TransactionDefinition.propagation_requires_new: cria uma nova transação e, se a transação existir atualmente, a transação atual será suspensa.
TransactionDefinition.propagation_supports: ingressar na transação se houver atualmente uma transação; Se atualmente não houver transação, ele continuará sendo executado de maneira não transacional.
TransactionDefinition.propagation_not_supported: é executado de maneira não transacional e, se houver atualmente uma transação, a transação atual será suspensa.
TransactionDefinition.propagation_Never: é executado de maneira não transacional, lança uma exceção se uma transação estiver presente atualmente.
TransactionDefinition.propagation_mandatory: participe da transação se houver atualmente uma transação; Se atualmente não houver transação, uma exceção será lançada.
TransactionDefinition.propagation_nested: Se uma transação estiver presente atualmente, uma transação será criada para ser executada como uma transação aninhada da transação atual; Se não houver transação, o valor será equivalente à transaçãoDefinition.propagation_required.
Tempo limite da transação
O chamado tempo limite da transação refere-se ao tempo máximo permitido por uma transação. Se o limite de tempo for excedido, mas a transação não tiver sido concluída, a transação será revertida automaticamente. Na TransactionDefinition, o tempo limite é representado pelo valor do INT, e sua unidade é de segundos.
A configuração padrão é o valor do tempo limite do sistema de transação subjacente. Se o sistema de transação de banco de dados subjacente não definir o valor do tempo limite, ele não é nenhum e não há limite de tempo limite.
Atributos somente leitura da transação
As transações somente leitura são usadas em situações em que o código do cliente é somente leitura, mas não modifica os dados. As transações somente leitura são usadas na otimização em cenários específicos, como quando usam o hibernato.
O padrão é lido e gravar transações.
Regras de reversão de transações de primavera
A maneira recomendada de instruir o Spring Transaction Manager a reverter uma transação é lançar uma exceção no contexto da transação atual. O gerente de transações de primavera pega exceções não tratadas e decide reverter a transação que lança a exceção com base nas regras.
Por padrão, a primavera reverterá apenas a transação se a exceção lançada for uma exceção desmarcada de tempo de execução, ou seja, a exceção lançada é uma subclasse da RuntimeTexception (os erros também causarão reversão de transações), enquanto lançar uma exceção verificada não causará reversão de transações.
É possível configurar explicitamente a transação para reverter quando essas exceções forem lançadas, incluindo exceções verificadas. Também é possível definir claramente as transações que não revoltam quando as exceções são lançadas.
Você também pode usar programaticamente o método setRollbackonly () para indicar que uma transação deve ser revertida. A única coisa que você pode fazer depois de chamar o setRollbackonly () é a reversão.
@Transaction Anotation
@Transactional Properties
| propriedade | tipo | descrever |
|---|---|---|
| valor | Corda | Descritor de qualificador opcional, especificando o gerente de transação para usar |
| propagação | Enum: propagação | Configurações opcionais de comportamento de propagação da transação |
| isolamento | Enum: isolamento | Configurações opcionais de nível de isolamento de transação |
| Readonly | booleano | Leia e escreva ou apenas transação somente leitura, leitura padrão e escreva |
| tempo esgotado | int (em segundos granularidade) | Configuração do tempo limite da transação |
| Rollbackfor | A matriz de objetos da classe deve ser herdada de arremesso | Matriz de classes de exceção que causam reversão de transações |
| RollbackForClassName | A variedade de nomes de classe deve ser herdada de arremesso | Array de nomes de classe de exceção que causam reversão de transações |
| Norollbackfor | A matriz de objetos da classe deve ser herdada de arremesso | Uma matriz de classe de exceção que não causa reversão de transações |
| NorollbackForClassName | A variedade de nomes de classe deve ser herdada de arremesso | Uma variedade de nomes de classe de exceção que não causarão reversão de transações |
uso
@Transaction pode atuar em interfaces, métodos de interface, classes e métodos de classe. Ao atuar em uma classe, todos os métodos públicos da classe terão propriedades de transação desse tipo. Ao mesmo tempo, também podemos usar essa anotação no nível do método para substituir a definição de nível de classe.
Embora a anotação @Transactional possa ser aplicada a interfaces, métodos de interface, classes e métodos de classe, a Spring recomenda não usar essa anotação em interfaces ou métodos de interface, porque isso só entrará em vigor ao usar um proxy baseado em interface. Além disso, a anotação @Transactional deve ser aplicada apenas ao método público, que é determinado pela natureza da Spring AOP. Se você usar a anotação @Transactional nos métodos de visibilidade protegida, privada ou padrão, isso será ignorado e nenhuma exceção será lançada.
Por padrão, apenas as chamadas de método de fora serão capturadas pelo proxy da AOP, ou seja, chamar outros métodos dentro desta classe dentro da classe não causará comportamento da transação, mesmo que o método chamado seja modificado usando a anotação @Transactional.
@Transactional (readonly = true) classe pública DefaultFooservice implementa fooservice {public Foo getFoo (string fooname) {// faça algo} // Essas configurações têm precedência para este método // o atributo de anotação (readnouling no método), o mesmo atribuição da classificação da classe @TransActation (readnlyingnly) updateFoo (foo foo) {// faça algo}}Resumir
O exposto acima é todo o conteúdo da interpretação deste artigo do uso da anotação @Transactional na primavera, e espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!