事务的操作
- mysql默认autocommit是开启的 value = 1. 当设置成0时,关闭自动提交。
- 也可以在不关闭autocommit的情况下,使用start transaction 或 begin,开始手动事务
select @@autocommit;
set @@autocommit = 0; -- 设置成手动提交
-- 开启事务
start transaction ;
begin ;
-- 提交事务
commit;
-- 回滚事务
rollback ;
事务四大特性
并发事务问题
脏读
一个事务中读取到了其他事务还没有提交的数据。
不可重复读
在一个事务内,多次读取同一条数据,在读取过程中,有另一个事务提交了对这个数据的修改,所以第一个事务内两次读取的数据不一致,就是不可重复读。
而解决不可重复读的现象是:在一个事务里,多次读取同一条数据时,结果始终相同,即使在这个事务的过程中有另一个线程已经修改了这个数据的记录,并且提交了,但是对于第一个事务内部,依然看不到最新的修改数据,依然和第一次读取到的数据相同,只有在提交了自己的时候后,再去读取同一条数据,才会查看到另一个事务修改后的数据。
幻读
幻读:在一个事务中先去查询是否存在一个数据,查询的结果不存在,在此时有另一个事务插入了数据(数据和第一个事务查询的条件相同)并且已经提交。这时第一个事务执行插入语句(条件相同),此时数据库会报错,数据已重复(id,unique),但是在自己的事务内查询依然查询不到(因为在满足不可重复读时,一个事务内的查询结果必定是一致的,所以查询不到另一个事务插入的数据,但是自己插入时会显示数据已存在)。
事务的隔离级别
查看隔离级别
-- 查看隔离级别 mysql 8.0 以后
SELECT @@TRANSACTION_ISOLATION;
-- 8.0之前
select @@tx_isolation;
select @@global.tx_isolation;
设置隔离级别
-- 设置隔离级别
set session transaction isolation level repeatable read;
set global transaction isolation level repeatable read;
Serializable (串行): 顾名思义,所有的修改数据库的sql,都会遵循先来后到。 性能最差
是怎么解决幻读的呢,数据库会根据哪个事务先开启的事务,先执行这个事务的的操作,在前一个事务没有提交前,后一个事务即使要修改数据库,也会一直阻塞等待。知道前一个事务提交后,才会执行后一个事务中的修改sql。
总结