relação transação nível de isolamento de transação MySQL e Primavera Introdução (reimpressão)

Transferência: https://blog.csdn.net/hellozhxy/article/details/81081187

Muito bom artigo, aprender sobre

nível de isolamento transação Introdução

Níveis de isolamento leitura suja leitura não repetível magia Reading
Uncommitted Read (leitura não consolidada) possível possível possível
Leia Comprometido (Leia comprometida) impossível possível possível
Leitura Repetida (leitura repetível) impossível impossível possível
Serialização (Serializáveis) impossível impossível impossível
  1. sujo dados lê são permitidos, o que é possível para ler transações não confirmadas de modificar outras sessões: leitura não consolidada (Leia Uncommitted)
  2. Leia Comprometido (Read Committed): você só pode ler os dados já apresentados. A maioria Oracle e outros bancos de dados é o nível padrão (não repetível lido)
  3. Leitura Repetida (repetida Read): Leia repetível. Dentro da mesma consulta transação hora de início da transação são consistentes, InnoDB o nível padrão. No padrão SQL, o nível de isolamento elimina leitura não repetível, mas há leitura fantasma, mas innoDB resolver o read phantom
  4. Serial Read (Serializable): totalmente serializado ler, cada leitura terá de obter um bloqueio no nível de tabela compartilhada, ler e escrever irá bloquear uns aos outros

Da próxima vez para verificar as características de cada nível de isolamento, antes de construir tudo de let uma mesa, nós estabelecemos uma conta para testar o nosso nível de conta de isolamento da transação tabela:

1 
2 
3 
4 
5 
6 
7
CRIAR conta TABELA ( 
    `int id` (11) não NULL AUTO_INCREMENT, 
    VARCHAR customer_name` (255) não nulo, 
    ` money` int (11) não nulo, 
    PRIMÁRIA CHAVE ( `id`), 
    ORIGINAL` uniq_name` USANDO BTREE ( customer_name) 
) MOTOR = `InnoDB` AUTO_INCREMENT = 10 Conjunto de caracteres predefinido utf8 AGRUPAR utf8_general_ci ROW_FORMAT = COMPACTO checksum = 0 DELAY_KEY_WRIT

RU (leia confirmada) leia nível de isolamento uncommitted

Primeiro, abra o Console A, e em seguida, definir o nível de isolamento da transação sessão para ler não confirmadas; em seguida, o mesmo aberto Console B, conjunto de ler não confirmadas;

1 
2 
3 
4 
5 
6 
7 
8 
9 
10
mysql> Conjunto de nível de isolamento transação sessão de ler não confirmadas; 
Query OK, 0 linhas afetadas (0,03 segundos) 
 
mysql> select @@ session.tx_isolation; 
+ ------------------------ + 
| @@ session.tx_isolation | 
+ ------------------------ + 
| LEIA-UNCOMMITTED | 
+ ------------------------ + 
1 linhas em conjunto (0,03 seg)

Nosso nível de isolamento transação dois console é ler não confirmadas, o seguinte teste estará acontecendo nível RU

resumo:

Modo pode ser encontrada no RU, uma transação de leitura para outro não confirmadas (o commit) os dados, resultando em leitura suja. Se a transação B é revertida, ele irá causar inconsistências de dados. RU é o menor nível de isolamento da transação.

RC (leitura confirmada) nível de isolamento READ COMMITTED

Agora vamos nível de isolamento transação está definido como RC (leitura confirmada)

1
session set nível de isolamento transação ler não confirmadas;


resumo

Nós modo RC, pode ser encontrado. Quando não há dados apresentados revisados ​​cometer no console B, consolar A leitura é menor do que os dados modificados, o que evita o sujo ler no modo RU, mas há um problema que vai encontrar a mesma operação no console A no. Dois dados selecionados não é o mesmo, não é um problema que não pode ser repetido .PS ler: RC nível de isolamento de transação é o banco de dados Oracle nível de isolamento padrão.

RR (Leia Repetitivo) Nível de Leitura Repetida Isolamento


resumo:

No nível RR, abordamos o problema da leitura não-repetível, que neste nível de isolamento, em uma transação que podemos garantir a ser capaz de obter os mesmos dados (mesmo se você tem outros assuntos para modificar os nossos dados). Mas não pode evitar leituras fantasmas, fantasma lê explicação simples é que há novos dados no tempo, não há nenhuma garantia inconsistente duas vezes para obter os dados, mas os bancos de dados diferentes têm diferentes implementações para diferentes níveis de RR, às vezes mais ou fechaduras gap para evitar leituras fantasmas.

InnoDB resolver o read phantom

A definição prévia de nível RR é susceptível de leitura produto fantasma, esta é a definição tradicional de nível RR aparecerá. No entanto, o uso de multi-versão MVCC controle de concorrência resolvido este problema no motor innoDB


É que phantom lê-lo? Na definição nível de isolamento padrão RR não pode ser resolvido leitura fantasma problema, por exemplo, eu quero assegurar leitura repetida, para que possamos adicionar uma fechadura (entre 1 e 11) na faixa de nosso conjunto de resultados, evitando alterações de dados. Mas nós afinal, não é realmente bloquear a tabela, inserir os dados de modo que não pode garantir que ele não está inserido. Então, é a existência de problemas de leitura fantasma. Mas resolve mecanismo InnoDB o problema da leitura fantasma, com base em MVCC (controle de concorrência multi-versão): Em InnoDB, irá adicionar dois valor oculto adicional após cada linha de dados para alcançar MVCC, estes dois valores de uma linha de registros de dados quando foi criado, além de um registro de dados quando esta linha expirado (ou excluído). Na prática, o armazenamento não é o tempo, mas o número da versão da transação, a cada abrir uma nova transação, o número da versão transação é incrementado. Assim, quando executar a atualização, o número da versão da transação corrente foi atualizado? Por isso, pode ser considerado leitura fantasma? ? (Duvidoso) principalmente gap gap leitura fantasma bloqueio + MVCC resolver o problema?

nível de isolamento de série:

tudo de série, mais alto nível de isolamento, o pior desempenho

Problemas?

No modelo RR, embora evitar o fantasma ler, mas há um problema, obter os dados em vez de dados em dados em tempo real, se é mais sensível ao serviço de dados em tempo real, o que é irrealista.
Para isso leia maneira dados históricos, podemos chamá-lo uma leitura snapshot (instantâneo lido), e ler a forma como a versão atual dos dados no banco de dados, chamadas a leitura atual (leitura atual). É claro que no MVCC em:

  • Snapshots leia-se: que seleccionar
    • Selecione * de mesa ... .;
  • leitura atual: Special ler, insert / update / operações de exclusão, pertencem à leitura atual, os dados atuais são processados, necessidade de bloqueio.
    • SELECT * FROM tabela onde? bloquear em modo de ação;
    • SELECT * FROM tabela onde? para atualização;
    • inserir;
    • atualizar;
    • excluir;

nível de isolamento transação realmente define o nível da leitura atual, MySQL, a fim de reduzir o processamento de bloqueio (incluindo à espera de outro bloqueio) tempo, aumentar a concorrência, introduziu o conceito de uma leitura instantâneo, então não selecione bloqueado. A atualização, inserir a "leitura atual" necessidade de módulos adicionais para resolver.

Por exemplo, temos o seguinte cenário de negócios fim, um único produto de nossa equipe operacional, temos que primeiro verificar o quanto o número de pedidos para a esquerda e, em seguida, o próximo single.

Transação 1:

1 
2
Num seleccionar a partir t_goods onde ID = 1; 
atualização t_goods definir num = nú- $ mynum onde id = 1;

Transação 2:

1 
2
Num seleccionar a partir t_goods onde ID = 1; 
atualização t_goods definir num = nú- $ mynum onde id = 1;

Supondo-se que este número apenas uma vez, o nosso próximo single é de apenas 1. Se no caso de transações simultâneas 1 há uma única consulta para se preparar para o próximo single, mas desta vez a transação 2 foi submetido. Ordens de se tornar 0. 1 nesta atualização execução da transação, que irá causar um acidente.

  1. Após a conclusão da libertao de bloqueio, é a utilização para o fecho de actualização de uma transacção mercadoria: 1 solução para o problema (bloqueio pessimista). Lembre-se que onde há índice de condições, caso contrário ele irá bloquear a tabela inteira.
  2. Solução 2 (bloqueio otimista): tabela de banco de dados para adicionar um campo de versão. Em seguida, reescrever o SQL:
1 
2
seleccionar num, versão de t_goods onde id = 1; 
atualização t_goods definir num = num-1, versão = verison + 1, onde id = 1 e versão = $ {version}

mecanismo de mola Transação

Primavera para uma série de transações processadas

nível de isolamento transação

Quando processados ​​em várias transações bloquear os dados, para assegurar a unidade de tempo de processamento de dados apenas uma transação, há situações diferentes para diferentes fechaduras

PADRÃO (padrão): Use o nível subjacente de isolamento da transação do banco de dados, o uso MySql select @@ tx_isolation pode consultar o nível de isolamento atual

READ_COMMITTED: Read Committed, ler os dados já apresentados, pode impedir sujo lê, mas não repetível leitura e leitura fantasma

READ_UNCOMMITTED: Leitura Não Confirmada, nenhum dado pode ser lido, arquivado, com menos

REPEATABLE_READ: Repetitivo ler, depois de ler o bloqueio automático, outras transações não podem ser modificados para abordar o sujo lê, leitura não repetível

SERIALIZABLE: serialização, uma fila de execução da transacção, a execução da transação após a conclusão do próximo

mecanismo de propagação de Transação

operações de banco de dados no serviço, como gerir os negócios das duas operações

REQUERIDO (padrão): Se uma transação não está neste momento transação aberta, qualquer transacção é automaticamente adicionado ao

REQUIRES_NEW: Para o chamador, o chamador, independentemente da existência de uma transação, o chamador criar um novo negócio.

OBRIGATÓRIO: Use a transação atual, se nenhuma transação, lançar uma exceção.

Aninhada: transações, transações aninhadas executado se houver, se não for o novo

Apoios: suporte para a transação atual, se nenhuma transação é executada de uma forma não-transacional.

NOT_SUPPORTED: executar uma operação de uma forma não-transacional, se a transação corrente existe, coloque a transação corrente pendente.

NUNCA: para executar maneira não transacional, se existe a transação corrente, uma exceção é lançada.

serviços de gestão de moda da mola.

programática de transação

programática de transação é o uso de assuntos codificação manual relacionadas com a lógica de negócios, esta abordagem é mais complicado, prolixo, mas mais flexível e pode ser controlado (favorito)

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13
testTransactionTemplate public void () { 
 
  TransactionTemplate transactionTemplate = new TransactionTemplate (txManager); 
  transactionTemplate.setIsolationLevel (TransactionDefinition.ISOLATION_READ_COMMITTED); //设置事务隔离级别
  transactionTemplate.setPropagationBehavior (TransactionDefinition.PROPAGATION_REQUIRED); //设置为necessário传播级别
  .... 
  transactionTemplate.execute (novo TransactionCallbackWithoutResult () { 
      @Override 
      protected void doInTransactionWithoutResult (status TransactionStatus) {//事务块
         JdbcTemplate .Update (insert_sql, "teste"); 
  }}); 
  
}

transação declarativa

  1. Para evitar manualmente cada vez que escrever código usando Spring AOP maneira de contornar o proxy para cada método, configuração xml uso para evitar escrever código.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<tx:advice id="txAdvice" transaction-manager="txManager"> 
<tx:attributes>  <!--设置所有匹配的方法,然后设置传播级别和事务隔离-->
           <tx:method name="save*" propagation="REQUIRED" /> 
           <tx:method name="add*" propagation="REQUIRED" /> 
           <tx:method name="create*" propagation="REQUIRED" /> 
           <tx:method name="insert*" propagation="REQUIRED" /> 
           <tx:method name="update*" propagation="REQUIRED" /> 
           <tx:method name="merge*" propagation="REQUIRED" /> 
           <tx:method name="del*" propagation="REQUIRED" /> 
           <tx:method name="remove*" propagation="REQUIRED" /> 
           <tx:method name="put*" propagation="REQUIRED" /> 
           <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> 
           <tx:method name="count*" propagation="SUPPORTS" read-only="true" /> 
          <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> 
          <tx:method name="list*" propagation="SUPPORTS" read-only="true" /> 
          <tx:method name="*" propagation="SUPPORTS" read-only="true" /> 
       </tx:attributes> 
</tx:advice> 
<aop:config> 
       <aop:pointcut id="txPointcut" expression="execution(* org.transaction..service.*.*(..))" /> 
       <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /> 
</aop:config>
  1. 同时也可以用注解的方式
1
<tx:annotation-driven transaction-manager="transactioManager" /><!--开启注解的方式-->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
   @AliasFor("transactionManager")
   String value() default "";
   @AliasFor("value")
   String transactionManager() default "";
   Propagation propagation() default Propagation.REQUIRED;//传播级别
  
   Isolation isolation() default Isolation.DEFAULT;//事务隔离级别
   int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;//事务超时时间
   boolean readOnly() default false;//只读事务
   Class<? extends Throwable>[] rollbackFor() default {};//抛出哪些异常 会执行回滚
   String[] rollbackForClassName() default {};
   Class<? extends Throwable>[] noRollbackFor() default {};
   String[] noRollbackForClassName() default {};//不回滚的异常名称
 
}
//transaction注解可以放在方法上或者类上

我们在这里不对两种事务编程做过多的讲解

Spring事务传播:

事务传播行为:

Spring管理的事务是逻辑事务,而且物理事务和逻辑事务最大差别就在于事务传播行为,事务传播行为用于指定在多个事务方法间调用时,事务是如何在这些方法间传播的,Spring共支持7种传播行为
为了演示事务传播行为,我们新建一张用户表

1
2
3
4
5
6
EATE TABLE user (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(255) NOT NULL,
    `pwd` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=`InnoDB` AUTO_INCREMENT=10 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT CHECKSUM=0 DELAY_KEY_WRITE=0;

Required:

必须有逻辑事务,否则新建一个事务,使用PROPAGATION_REQUIRED指定,表示如果当前存在一个逻辑事务,则加入该逻辑事务,否则将新建一个逻辑事务,如下图所示;

测试的代码如下,在account插入的地方主动回滚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public int insertAccount(final String customer, final int money) {
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);//设置为required传播级别
   int re= transactionTemplate.execute(new TransactionCallback<Integer>() {
        public Integer doInTransaction( TransactionStatus status) {
            int i = accountDao.insertAccount(customer, money);
            status.setRollbackOnly();//主动回滚
            return i;
        }
    });
    return re;
}
 public int inertUser(final String username, final String password) {
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);//设置为required传播级别
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                int i = userDao.inertUser(username, password);
                int hahha = accountService.insertAccount("hahha", 2222);
//                status.setRollbackOnly();
                System.out.println("user==="+i);
                System.out.println("account===="+hahha);
            }
        });
        return 0;
    }

按照required的逻辑,代码执行的逻辑如下:

  1. 在调用userService对象的insert方法时,此方法用的是Required传播行为且此时Spring事务管理器发现还没开启逻辑事务,因此Spring管理器觉得开启逻辑事务
  2. 在此逻辑事务中调用了accountService对象的insert方法,而在insert方法中发现同样用的是Required传播行为,因此直接使用该已经存在的逻辑事务;
  3. 返回userService,执行完并关闭事务

所以在这种情况下,两个事务属于同一个事务,一个回滚则两个任务都回滚。

RequiresNew:

创建新的逻辑事务,使用PROPAGATION_REQUIRES_NEW指定,表示每次都创建新的逻辑事务(物理事务也是不同的)如下图所示:

Supports:

支持当前事务,使用PROPAGATION_SUPPORTS指定,指如果当前存在逻辑事务,就加入到该逻辑事务,如果当前没有逻辑事务,就以非事务方式执行,如下图所示:

NotSupported:

不支持事务,如果当前存在事务则暂停该事务,使用PROPAGATION_NOT_SUPPORTED指定,即以非事务方式执行,如果当前存在逻辑事务,就把当前事务暂停,以非事务方式执行。

Mandatory:

必须有事务,否则抛出异常,使用PROPAGATION_MANDATORY指定,使用当前事务执行,如果当前没有事务,则抛出异常(IllegalTransactionStateException)。当运行在存在逻辑事务中则以当前事务运行,如果没有运行在事务中,则抛出异常

Never

不支持事务,如果当前存在是事务则抛出异常,使用PROPAGATION_NEVER指定,即以非事务方式执行,如果当前存在事务,则抛出异常(IllegalTransactionStateException)

Nested:

嵌套事务支持,使用PROPAGATION_NESTED指定,如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则创建一个新的事务,嵌套事务使用数据库中的保存点来实现,即嵌套事务回滚不影响外部事务,但外部事务回滚将导致嵌套事务回滚。

Nested和RequiresNew的区别:

  1. RequiresNew每次都创建新的独立的物理事务,而Nested只有一个物理事务;
  2. Nested嵌套事务回滚或提交不会导致外部事务回滚或提交,但外部事务回滚将导致嵌套事务回滚,而 RequiresNew由于都是全新的事务,所以之间是无关联的;
  3. Nested使用JDBC 3的保存点(save point)实现,即如果使用低版本驱动将导致不支持嵌套事务。

    使用嵌套事务,必须确保具体事务管理器实现的nestedTransactionAllowed属性为true,否则不支持嵌套事务,如DataSourceTransactionManager默认支持,而HibernateTransactionManager默认不支持,需要设置来开启。

Acho que você gosta

Origin www.cnblogs.com/libin2015/p/12556163.html
Recomendado
Clasificación