Base de datos MySQL: transacción MySQL

1. Concepto

Serie de pasos (operaciones) necesarios para completar algo. Estas operaciones tienen éxito o fracasan al mismo tiempo.

2. Operaciones básicas de transacciones.

Zhang San y Li Si tienen cada uno 1.000 yuanes en sus cuentas. Ahora Zhang San transfiere 500 yuanes a Li Si.

-- 1 创建account表
create table tb_account(
id int(11) auto_increment,
user_name varchar(30) not null,
account_blance  int(11) not null, -- 账户余额
primary key (id)    
)ENGINE=INNODB,default charset =UTF8;

-- 2 插入数据
insert into tb_account(user_name,account_blance)
values('ZS',1000),('LS',1000);

-- 3 执行张三向李四转账500
-- ZS账户-500,LS账户+500
-- 下面两个update语句要么同时执行成功要么同时执行失败
-- 执行下列SQL语句会出现问题:张三的钱减少了,李四的钱没有加上。因为此时的两个update语句并没有使用事务来托管
update tb_account set account_blance=account_blance-500 where id=1;
-- 银行转帐异常情况:如机机房停电
update tb_account set account_blance=account_blance+500 where id=2;

3. Cuatro características de los asuntos

Atomicidad : cada paso de la transacción no se puede volver a dividir

Consistencia : Las cuentas de Zhang San y Li Si tienen un total de 2000 yuanes. No importa cuántas transferencias se realicen, el monto total permanece sin cambios.

Persistencia : cuando una transacción se ejecuta correctamente (se completa), los datos se conservarán en el archivo de datos del disco. Por ejemplo, si la transferencia se realiza correctamente: el saldo de Zhang San pasa a ser 500 y el saldo de Li Si pasa a ser 1500.

Aislamiento : la transacción A y la transacción B operan con un dato al mismo tiempo y no se afectan entre sí.

4. Cómo enviar transacciones,

1) Envío automático

No es necesario escribir una confirmación; la declaración DML se enviará automáticamente de forma persistente.

2) Envío manual

--El resultado de la consulta es 1 para envío automático y 0 para envío manual.

select @@autocommit;

- Modificar el método de envío (cambiar el envío automático al envío manual)

set @@autocommit = 0 ;

5. Operaciones básicas de transacciones.

1 Iniciar una transacción

start transaction;

2 Confirmar la transacción

commit;

3 transacción de reversión

rollback;

Nota: Una vez que utilice Iniciar transacción, para abrir una transacción, el envío automático no será válido.

  Si todas las operaciones se ejecutan normalmente use commit; confirme la transacción

  Cuando ocurre una excepción y se revierte una transacción, los datos (en este caso, la tabla tb_account) generalmente se revierten al estado anterior a que se iniciara la transacción.

6. Operación de transferencia

-- 1 开启事务
start transaction;
-- 2 执行SQL语句
update tb_account set account_blance=account_blance-500 where id=1;
 手机转账异常情况:转账过程中手机没电了
update tb_account set account_blance=account_blance+500 where id=2;
-- 3 如果SQL语句全部执行成功就提交事务,如果其中任何一步执行失败,立刻回滚事务
-- 此时第一个update执行成功,第二个update语句执行失败了,并没有提交事务,查询结果如下:
select * from tb_account;
/*
+----+-----------+----------------+
| id | user_name | account_blance |
+----+-----------+----------------+
|  1 | ZS        |            500 |
|  2 | LS        |           1000 |
+----+-----------+----------------+
*/
-- 问题:张三账户的余额减少了,李四账户余额没有增加。这就是脏数据
-- 此时需要将脏数据回滚到开启事务之前
rollback;
-- 回滚完毕再次查询
select * from tb_account;
-- 此时事务回滚到开启之前的状态
/*
+----+-----------+----------------+
| id | user_name | account_blance |
+----+-----------+----------------+
|  1 | ZS        |           1000 |
|  2 | LS        |           1000 |
+----+-----------+----------------+
*/
-- 一个事务一旦开启了,在没有执行commit;或者rollback;之前事务不会结束
-- 相关面试题:工作中有没有用到事务?请解释事务的概念?不使用事务会发生什么问题?使用事务能够解决什么问题?解释事务的四大特征[隔离级别]?

7. Nivel de aislamiento de transacciones

nivel de aislamiento de transacciones

lectura sucia

lectura no repetible

lectura fantasma

lectura no confirmada

lectura comprometida

No

Lectura repetible

No

No

serializable

No

No

No

 Nivel de aislamiento de consultas

select @@tx_isolation

En el trabajo: no se utiliza ni 1 ni 4, solo se cambia entre 2 y 3

El nivel de aislamiento de transacciones predeterminado de MySQL es 3 y el nivel de aislamiento predeterminado de Oracle es 2.

SELECT @@global.tx_isolation; //查询全局事务
SELECT @@session.tx_isolation; //查询当前会话事务

establecer el nivel de aislamiento de transacciones

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
//测试可以不用设置全局事务
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
//(这个可以不用设,只设置上面一行就可以了进行测试了)

Lectura sucia:

Una transacción (A) lee datos no confirmados de otra transacción (B) (rompiendo el aislamiento).

  Por ejemplo: la transacción A abre una transacción para transferencia y la instrucción DML se ejecuta exitosamente pero sin confirmación; la transacción B se abre en otra ventana y la instrucción Select se ejecuta para leer los datos de tb_account y el resultado de la lectura son los datos que la transacción A no se ha enviado.

Lectura no repetible:

Los datos leídos varias veces en la misma transacción son inconsistentes ( rompiendo la coherencia, actualizando y eliminando)

  Por ejemplo: la transacción A abre una transacción para transferencia y la instrucción DML se ejecuta exitosamente pero sin confirmación; la transacción B se abre en otra ventana y la instrucción Select se ejecuta para leer los datos de tb_account y el resultado de la lectura es correcto (1000 , 1000).

  Se envió una transacción en la transacción A. Luego la transacción B realiza la operación Seleccionar nuevamente y el resultado de la consulta es correcto (500,1500)

  Problema: la transacción B realizó dos operaciones de selección en la tabla tb_account en una transacción y los resultados de la consulta de las dos operaciones fueron inconsistentes.

Lectura fantasma:

La transacción A inserta un dato y puede usar select para obtener el resultado. En este momento, la transacción B inserta un dato o una gran cantidad de datos casi al mismo tiempo. En este momento, la transacción A no puede ver la actualización de la transacción B. (rompiendo la consistencia, insertar ).

leer prueba de lectura sucia no confirmada:

f67e3147f2ff45fbbed5c9a1edb7c4f5.png

 Cuando se inicia una transacción, otra transacción puede leer las actualizaciones del extracto de esta transacción sin un envío confirmado.

¿Cómo solucionar el problema de la lectura sucia? Modificar el nivel de aislamiento de la transacción: lectura confirmada

set session transaction isolation level read committed;

5daaa016c45a40418485f6987095cc4c.png

¿Cómo solucionar el problema de lectura no repetible? Establezca el nivel de aislamiento de la transacción en "lectura repetible" lectura repetible 

076df366e0d4488d9f087aba635263af.png

Demostración del problema de lectura fantasma:

bddd074a429642bc858db7ac0a4fb183.png 

Pruebas serializables

Puede resolver todos los problemas, pero es ineficiente, similar al sincronizado de Java.

Java usa sincronizado para bloquear objetos. MySQL usa serializable para bloquear la tabla. La transacción A inicia la transacción y realiza operaciones DML, pero no se envía. En este momento, la transacción B inicia la transacción y realiza la operación de selección, pero no se consulta ningún dato porque la tabla tb_account está ocupada (bloqueada) por la transacción A en este momento.

set session transaction isolation level serializable;

 3d470f16220b417aa5cfec7b7a5c0db8.png

 

 

Supongo que te gusta

Origin blog.csdn.net/shengshanlaolin_/article/details/128460801
Recomendado
Clasificación