English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Explicação Detalhada da Gestão de Transações do Springboot

No gerenciamento de transações do Spring Boot, implemente a interface PlatformTransactionManager.

public interface PlatformTransactionManager {
  org.springframework.transaction.TransactionStatus getTransaction(org.springframework.transaction.TransactionDefinition transactionDefinition) throws org.springframework.transaction.TransactionException;
  void commit(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException;
  void rollback(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException;
}

Quando usarmos o spring-boot-starter-Quando há dependência de JDBC, a framework injetará automaticamente DataSourceTransactionManager. Portanto, não é necessário qualquer configuração adicional para usar a anotação @Transactional.

Gerenciador de transações JDBC

No Service, métodos anotados com @Transactional suportarão transações. Se a anotação estiver na classe, todos os métodos da classe terão suporte de transação por padrão.

Situação de gerenciamento de múltiplas transações

Um: pode-se implementar a interface TransactionManagementConfigurer, onde o valor retornado pelo método é o gerenciador de transações padrão.

Dois: pode-se definir o valor no método de execução específico

Se o contêiner do Spring contiver várias instâncias de PlatformTransactionManager e não implementar a interface TransactionManagementConfigurer para definir um valor padrão, quando usarmos a anotação @Transactional em um método, será necessário especificar o valor com o atributo value. Se não for especificado, será lançada uma exceção.

//@EnableTransactionManagement // Ativa a gestão de transações anotadas, equivalente ao arquivo de configuração xml <tx:annotation-driven />
@SpringBootApplication
public class ProfiledemoApplication implements TransactionManagementConfigurer {
  @Resource(name="txManager2}
  private PlatformTransactionManager txManager2;
  // criar manualmente o gerenciador de transações1 o framework datasource será injetado automaticamente
  //No container Spring, a anotação @Bean definida manualmente será carregada prioritariamente, e o framework não reinstanciará outros classes de implementação de PlatformTransactionManager.
  @Bean(name = "txManager1}
  public PlatformTransactionManager txManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
  }
  // criar gerenciador de transações2
  @Bean(name = "txManager2}
  public PlatformTransactionManager txManager2(EntityManagerFactory factory) {
    return new JpaTransactionManager(factory);
  }
  // Implementa o método da interface TransactionManagementConfigurer, cujo valor de retorno representa o gerenciador de transações padrão a ser usado quando há vários gerenciadores de transações
  @Override
  public PlatformTransactionManager annotationDrivenTransactionManager() {
    return txManager2;
  }
  public static void main(String[] args) {
    SpringApplication.run(ProfiledemoApplication.class, args);
  }
}

implementação específica

@Component
public class DevSendMessage implements SendMessage {
  // usando value para especificar qual gerenciador de transações deve ser usado
  @Transactional(value="txManager1}
  @Override
  public void send() {
    System.out.println(">>>>>>>>Dev Send()<<<<<<<<");
    send2();
  }
  @Transactional
  public void send2()) {
    System.out.println(">>>>>>>>Dev Send2()<<<<<<<<");
  }
}

Nível de isolamento

public enum Isolation {
  DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
  READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
  READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
  REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
  SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
  private final int value;
  Isolation(int value) { this.value = value; }
  public int value() { return this.value; }
}
  1. DEFAULT: esse é o valor padrão, que representa o nível de isolamento padrão do banco de dados subjacente. Para a maioria dos bancos de dados, esse valor geralmente é: READ_COMMITTED.
  2. READ_UNCOMMITTED: esse nível de isolamento indica que uma transação pode ler os dados que foram modificados por outra transação mas ainda não foram submetidos. Esse nível não pode evitar a leitura suja e a leitura não repetível, portanto, esse nível é raramente usado.
  3. READ_COMMITTED: esse nível de isolamento indica que uma transação pode ler apenas os dados que foram submetidos por outra transação. Esse nível pode evitar a leitura suja, que é a recomendação mais comum.
  4. REPEATABLE_READ: esse nível de isolamento indica que uma transação pode repetir várias vezes a execução de uma consulta durante todo o processo e que cada vez que a consulta é retornada, os registros são os mesmos. Mesmo que novos dados que atendem à consulta sejam adicionados entre várias consultas, esses novos registros serão ignorados. Esse nível pode evitar a leitura suja e a leitura não repetível.
  5. SERIALIZABLE: todas as transações são executadas sequencialmente um por um, de modo que as transações não podem interferir umas com as outras, o que significa que esse nível pode evitar a leitura suja, a leitura não repetível e a leitura fantasma. No entanto, isso pode afetar significativamente o desempenho do programa. Geralmente, esse nível não é usado.

Especificar o método: através da configuração da propriedade isolation, por exemplo:

@Transactional(isolation = Isolation.DEFAULT)

Comportamento de propagação

O comportamento de propagação de transações se reflete a situação em que, antes de iniciar a transação atual, já existe um contexto de transação, e existem várias opções para especificar o comportamento de execução de um método transacional.

Podemos ver que a classe enum Propagation definida em org.springframework.transaction.annotation.Propagation6várias constantes representam os valores de comportamento de propagação:

public enum Propagation {
  REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
  SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
  MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
  REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
  NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
  NEVER(TransactionDefinition.PROPAGATION_NEVER),
  NESTED(TransactionDefinition.PROPAGATION_NESTED);
  private final int value;
  Propagation(int value) { this.value = value; }
  public int value() { return this.value; }
}

REQUIRED: Se houver uma transação atual, junte essa transação; se não houver transação, crie uma nova transação. Valor padrão.

SUPPORTS: Se houver uma transação atual, junte essa transação; se não houver transação, continue executando de forma não transacional.

MANDATORY: Se houver uma transação atual, junte essa transação; se não houver transação, lance uma exceção. (Forçado a ser colocado dentro da transação)

REQUIRES_NEW: Crie uma nova transação, se houver uma transação atual, suspenda a transação atual. (Usado frequentemente para registrar logs, mesmo que a transação anterior seja rollbackada, esta transação será executada e registrará as informações de erro.)

NOT_SUPPORTED: Execute de forma não transacional, se houver uma transação atual, suspenda a transação atual.

NEVER: Execute de forma não transacional, se houver uma transação atual, lance uma exceção.

NESTED: Se houver uma transação atual, crie uma transação aninhada para executar como transação atual; se não houver transação atual, o valor é equivalente a REQUIRED.

Método especificado: use a propriedade propagation para configurar, por exemplo:

@Transactional(propagation = Propagation.REQUIRED)

Situações em que não há rollback

Somente quando ocorrer um RuntimeException não capturado, o rollback será executado

catch a exceção lançada, ambas as inserções terão sucesso

@Override
  @Transactional
  public void insertandinsert(Staff staff) {
    staffDao.insert(staff);
    try {
      int i = 1 / 0;
    }
      e.printStackTrace();
    }
    staffDao.insert(staff);
  }

Adicione a instrução TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); na cláusula catch do método da camada de serviço, para rollback manualmente e evitar a inserção de dados.

@Override
  @Transactional
  public void insertandinsert(Staff staff) throws Exception {
    try {
      staffDao.insert(staff);
      int i=1/0;
      staffDao.insert(staff);
    }
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
  }

Isso é o conteúdo completo deste artigo. Esperamos que ajude na aprendizagem de todos e que todos apoiem o tutorial de gritaria.

Declaração: o conteúdo deste artigo é extraído da internet, pertencente ao proprietário original, postado pelos usuários da internet de forma voluntária. Este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidades legais relevantes. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie um e-mail para: notice#oldtoolbag.com (ao enviar e-mail, substitua # por @ para denunciar e forneça provas relevantes. Se confirmado, o site deletará imediatamente o conteúdo suspeito de violação de direitos autorais.)

Você também pode gostar