Mysql之事务

119 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

什么是事务

事务原则:ACID原则

1、原子性(Atomicity)

要么都成功,要么都失败

例如转账时,要么转钱和收钱都成功,要么都失败

2、一致性(Consistency)

事务前后的数据完整性要保持一致

两人转账前后的钱包总金额数不变

3、持久性(Durability)

事务一旦提交则不可逆,被持久化到数据库中

4、隔离性(Isolation)

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,事务之间要互相隔离。

对于任意两个并发的事务1和事务2,要么事务1在执行前事务2就执行完了,要么事务1在执行完了再执行事务2,就像单线程一样。

5、隔离级别

  • 读未提交(最低的级别):read uncommitted

    事务1可以读取到事务2未提交的数据(脏读)

  • 读已提交

    事务1只能读到事务2提交后的数据(不可重复读)

    oracle 默认

  • 可重复读

    事务1开启后,不论多久,每次在事务1中读到的数据都是一致的。即使事务2把数据修改,并提交了,事务1读的数据还是不变

    mysql默认的事务隔离级别!!!

  • 序列化/串行化(最高)

    效率最低,解决了所有问题

    表示事务排队,不能并发

脏读:

指一个事务读取了另外一个事务未提交的数据

不可重复读:

在一个事务内读取表中的某一行数据,多次读取结果不同。就是一个事务再次读取时,那个数据变成了另一个事务提交后的数据,使该两次读取的数据不一致。

虚读(幻读):

指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。和不可重复读的区别是,幻读是多个/多行数据,不可重复读是一个/一行。

使用格式

set autocommit = 0 --关闭
set autocommit = 1 --开启(默认)
​
​
--手动处理事务
set autocommit = 0; --关闭自动提交
​
--事务开启
start transaction --标记一个事务的开始,从这个之后的sql都在同一个事务里
​
...
​
--提交:持久化
commit
​
--回滚:回到原来的样子
rollback
​
--事务结束
set autocommit = 1 --开启自动提交
​
savepoint 保存点名 --设置一个事务的保存点
rollback to savepoint 保存点名 --回滚到保存点
release savepoint 保存点名 --撤销保存点

样例

--创建一个数据库
create database shop character set utf8 collate utf_8_general_ci
use shop 
​
--创建一个表
create table `account`(
    `id` int(3) not null auto_increment,
    `name` varchar(30) not null,
    `money` decimal(9, 2) not null,
    primary key (`id`)
)engine = innodb default charset = utf8
​
--插入值
insert into account(`name`,`money`) values ('A', 2000.00), ('B', 10000.00);
​
--模拟转账:事务
set autocommit = 0; --关闭自动提交
start transaction; --开启一个事务
​
--A给B转账500
update account set money = money - 500 where name = 'A';
update account set money = money + 500 where name = 'B';
​
commit; --提交事务
rollback; --回滚
​
set autocommit = 1; --恢复默认值