1、事务概述
1.1什么是事务
MySQL
事务主要是处理操作量⼤,复杂度⾼的数据。
1.2事务的应用的场景
库存管理
在电商、物流等场景中,库存管理是一个非常关键的业务。使用事务可以保证库存操作的一致性,避免因为多个操作同时执行,导致数据错误的情况。
1.3事务的提交方式
手动提交
自动提交
2、事务手动提交方式
事务执⾏成功的过程:开启事务
->
执⾏多条件
SQL
语句
->
成功
-
>
事务提交
事务执⾏失败的过程:开启事务
->
执⾏多条件
SQL
语句
->
失败
-
>
事务回滚
2.1语法格式
格式:start transaction ; # 开启事务commit ; # 提交事务rollback ; # 回滚事务
案例:
事务的成功提交:模拟张三给李四转
500
元钱(成功) ⽬前
# 开启事务mysql> start transaction ;Query OK, 0 rows affected ( 0.01 秒 )# 执⾏从张三帐户扣出 500 元mysql> update yh set money=money- 500 wherename= ' 张三 ' ;Query OK, 1 rows affected ( 0.01 秒 )# 执⾏往李四帐户加⼊ 500 元mysql> update yh set money=money+ 500 wherename= ' 李四 ' ;Query OK, 1 rows affected ( 0.01 秒 )# 提交事务mysql> commit ;Query OK, 0 rows affected ( 0.08 秒 )# 查看帐户mysql> select * from yh
事务回滚:模拟李四给张三转
500
元钱(失败)
# 开启事务mysql> start transaction ;Query OK, 0 rows affected ( 0.02 秒 )# 执⾏从李四帐户扣出 500 元mysql> update yh set money=money- 500 wherename= ' 李四 ' ;Query OK, 1 rows affected ( 0.01 秒 )# 执⾏往张三帐户加⼊ 500 元,但是加了 600mysql> update yh set money=money+ 600 wherename= ' 张三 ' ;Query OK, 1 rows affected ( 0.01 秒 )# 事务回滚mysql> rollback ;Query OK, 0 rows affected ( 0.02 秒 )# 查看帐户mysql> select * from yh;
3、事务自动提交
MySQL
默认每⼀条
DML(
增删改
)
语句都是⼀个单独的事务,
每条语句都会⾃动开启⼀个事务,语句执⾏完毕⾃动提交事
务,
MySQL
默认开始⾃动提交事务。
如:
事务开始
->update/delete/insert into->
事务提交
案例:
⾃动事务提交:往张三的帐户⾥存⼊ 1000mysql> update yh set money=money+ 1000 where 元name= ' 张三 ' ;Query OK, 1 rows affected ( 0.05 秒 )mysql> select * from yh;
3.1取消自动提交
查看MySql是否开启自动提交事务
格式:select @@autocommit ;
注意:
@@
表示全局变量,
1
表示开启,
0
表示关闭
取消⾃动提交事务
格式:set autocommit = 0 ;
案例:
从李四的帐户取出
1000
元,
注意:
要在窗⼝
A
、窗⼝
B
中验证
#
窗⼝
A
mysql>
update
yh
set
money=money-
1000
where
name=
'
李四
'
;
Query
OK,
1
rows affected (
0.01
秒
)
mysql>
select
*
from
yh;
#
在窗⼝
B
中查询银⾏帐户
(
第⼀次验证
)
#
提交
mysql>
commit;
#
在窗⼝
B
中查询银⾏帐户
(
第⼆次验证
)
再打开一个窗口
#
窗⼝
B
mysql>
select
*
from
yh;
4、事务原理
⼀个事务会涉及到⼤量的
cpu
计算和
IO
操作,这些操作被打包
成⼀个执⾏单元
,
要么同时都完成,要么同时都不完成
4.1
、⾃动提交原理图
如果没有显示启动事务
,
数据库会根据
autocommit
的值
.
默认
每条
sql
操作都会⾃动提交。
4.2
、⼿动提交原理图
如果开启了事务,其中有任何⼀条语句因为崩溃或者其它原因
⽆法执⾏,那么该组中所有的
sql
语句都不会执⾏。
4.3
、事务提交步骤
客户端连接上服务器端,创建连接同时创建当前⽤户的临时事
务⽇志⽂件。
开启事务,改变原有的操作机制(所有的操作都会先写⼊临时
⽇志⽂件)。
写⼊
SQL
,接收并执⾏
SQL
,所有的
SQL
操作都会写⼊临时⽂
件;返回数据时,从数据库表拿取数据,但要通过临时⽇志⽂
件加⼯在返回。
事务的提交或回滚,提交:同步临时⽇志⽂件中的
SQL
操作结
果到数据库表;回滚:清除临时⽇志⽂件
5
、事务回滚
我们可以在
mysql
事务处理过程中定义保存点
(SAVEPOINT)
,
然后回滚到指定的保存点前的状态。
定义保存点,以及回滚到指定保存点前状态的语法如下:
格式:savepoint 保存点名 ; # 定义保存点rollback to savepoint 保存点名 ; # 回滚到指定保存点或rollback to 保存点名 ;
数据表准备
# 创建⼀个管理员表create table manager(id int primary key auto_increment ,uname varchar ( 20 ),pword varchar ( 20 ));# 插⼊数据insert into manager(uname,pword)values ( 'zhangsan' , 'zhangsan' ),( 'lisi' , 'lisi' );# 插⼊数据insert into manager(uname,pword)values ( 'wangwu' , 'wangwu' ),( 'zhaoliu' , 'zhaoliu' );
案例:
开启事务向表中插⼊⼆条件记录设置保存点,保存点的名字为: insert_point向表中插⼊⼆条件记录回到保存点: insert_pointmysql> start transaction ;Query OK, 0 rows affected ( 0.01 秒 )mysql> insert into manager(uname,pword)values ( 'zhangsan' , 'zhangsan' ),( 'lisi' , 'lisi' );Query OK, 2 rows affected ( 0.01 秒 )mysql> select * from manager;+----+----------+----------+| id | uname | pword |+----+----------+----------+| 1 | zhangsan | zhangsan || 2 | lisi | lisi |+----+----------+----------+2 ⾏于数据集 ( 0.01 秒 )mysql> savepoint insert_point;Query OK, 0 rows affected ( 0.01 秒 ) mysql> insert into manager(uname,pword)values ( 'wangwu' , 'wangwu' ),( 'zhaoliu' , 'zhaoliu' );Query OK, 2 rows affected ( 0.01 秒 )mysql> select * from manager;+----+----------+----------+| id | uname | pword |+----+----------+----------+| 1 | zhangsan | zhangsan || 2 | lisi | lisi || 3 | wangwu | wangwu || 4 | zhaoliu | zhaoliu |+----+----------+----------+4 ⾏于数据集 ( 0.01 秒 )mysql> rollback to savepoint insert_point;Query OK, 0 rows affected ( 0.00 秒 )mysql> select * from manager;+----+----------+----------+| id | uname | pword |+----+----------+----------+| 1 | zhangsan | zhangsan || 2 | lisi | lisi |+----+----------+----------+2 ⾏于数据集 ( 0.01 秒 )
注意:
设置保存点可以让我们在失败的时候回到保存点,⽽不是回到
事务开启的时候。
6
、事务隔离级别
6.1
、事务特性
原⼦性(
Atomicity
):
事务内的操作要嘛全部完成,要嘛全
部回滚。
⼀致性
(Consistency)
:
事务执⾏的前后都是合法的数据状
态,不会违反任何的数据完整性。
隔离性(
Isolation
)
:
主要是事务之间的相互的影响,根据隔
离有不同的影响效果。
持久性(
Durability
):
事务⼀旦提交,就会体现在数据库
上,不能回滚。
6.2
、事务的并发问题
脏读:
⽐如事务
A
执⾏的过程中,读到了事务
B
未提交的内
容。
不可重复读:
指⼀个事务在前后两次查询的结果不⼀致。
幻读:
幻读是指前后两次相同条件下的查询,后⼀次查询读到
了前⼀次查询没有的⾏数据。
6.3
、事务的隔离级别
注意:
隔离级别越⾼,性能越差,安全性越⾼
6.4
、事务隔离命令
查看隔离级别
# 格式:select @@transaction_isolation ;mysql> select @@transaction_isolation ;+-------------------------+| @@transaction_isolation |+-------------------------+| REPEATABLE - READ |+-------------------------+1 ⾏于数据集 ( 0.01 秒 )
设置隔离级别
# 格式:set global transaction_isolation= 级别字符串mysql> set global transaction_isolation= 'readcommitted' ;Query OK, 0 rows affected ( 0.01 秒 )
mysql> select @@transaction_isolation ;+-------------------------+| @@transaction_isolation |+-------------------------+| READ - COMMITTED |+-------------------------+1 ⾏于数据集 ( 0.02 秒 )
7、脏读
7.1设置隔离级别
mysql> set global transaction_isolation= 'readuncommitted' ;Query OK, 0 rows affected ( 0.00 秒 )# 重启窗⼝查看隔离级别mysql> select @@transaction_isolation ;+-------------------------+| @@transaction_isolation |+-------------------------+| READ - UNCOMMITTED |+-------------------------+1 ⾏于数据集 ( 0.02 秒 )
7.2脏读
脏读是⽐较危险的事情,如果张三在李四那⾥买了⼀个汽球花
了
500
元,那么张三转帐给李四后,李四发货给张三,张三收
到货物后把事务回滚,这样李四再也没有看到钱
8
、不可重复读
8.1
、设置隔离级别
恢复
yh
表中的数据为:
打开
A
,
B
两个窗⼝,分别开启事务:
mysql> set global transaction_isolation= 'readcommitted' ;Query OK, 0 rows affected ( 0.00 秒 )# 重启窗⼝查看隔离级别mysql> select @@transaction_isolation ;+-------------------------+| @@transaction_isolation |+-------------------------+| READ - COMMITTED |+-------------------------+
1
⾏于数据集
(
0.02
秒
)