定义
- 事务是一组操作的集合,它是一个不可分割的工作单位。
- 事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,这些操作要么同时成功,要么同时失败
流程
开启事务---->提交事务
如果中间出现了异常,就回滚事务
回滚事务指的是将修改的数据恢复
注意:MYSQL中默认事务自动提交,即执行DML语句的时候MYSQL会立即隐式的提交事务.
事务的操作演示
以转账为例
假定有这样一个账单
账户 | 余额 |
---|---|
张三 | 2000 |
李四 | 2000 |
现进行以下操作
-
查询张三的余额
select * from account where name='张三';
-
对张三的余额-1000
update account set money=money-1000 where name='张三';
-
对李四的余额+1000
update account set money=money+1000 where name='李四';
对这三条指令在同一时间执行那么表会变成
账户 | 余额 |
---|---|
张三 | 1000 |
李四 | 3000 |
假定2--3中存在SQL语句A,且A中SQL语句必然不能执行成功
这张表就会变成
账户 | 余额 |
---|---|
张三 | 1000 |
李四 | 2000 |
那么将1,2,A,3的代码在同一时间执行,就会出现1,2执行成功A,3执行不超过
这时候我们回滚事务回复即可。
在MYSQL中每一条DML语句都是一个单独的事务,并且默认自动提交。
事务的执行语法
查看事务提交方式
Select @@autocommit;
如果是1代表手动提交,0代码自动提交。在MYSQL中@@代表系统变量,@代表用户自定义变量。
设置事务的提交方式
Set @@autocommit=0或者1;(这个是将整个控制台提交方式的修改)
或者
begin; 开启事务
Start transcation; 开启事务
提交事务
commit;
回滚事务
rollback;
一般事务用法:
begin或start transcation
SQL语句
commit;
出现错误
回滚事务
roolback;
事务的四大特性(ACID)
原子型(Atomicity)
事务是不可分割的最小操作单位,要么全部成功要么全部失败
一致性(Consistency)
事务完成时,必须使所有数据保持一致的状态
隔离性(Isolation)
数据库提供的隔离机制,保证事务不受外部并发操作的影响的独立环境运行
持久性(Durability)
事务一旦提交或回滚,他对数据库中的数据影响是永久的
并发事务产生的问题
A事务和B事务同时操作同一张表引发的问题叫并发事务问题
就多个操作端,同时操作一张表产生的问题。
脏读
事务A读取到了事务B未提交的数据
过程
- 事务A查询表内容
- 事务B更新表内容(并未提交!)
- A事务再次查询表内容时读取到了事务B并未提交的内容。
代码过程
事务A的客户端(数字代表执行顺序)
1. begin; ->客户端A开启事务
3. select * from account where id=1; ->事务A查询id=1的内容
5. select * from account where id=1; ->事务A再次查询id=1的内容
6.读取到了客户端B未提交的数据
事务B的客户端
2. begin; ->客户端B开启事务
4. update account set mone=money-1000 where id=1; ->事务B更新id=1的数据
A事务读取到了B事务未提交的数据就叫脏读
不可重复读
在一个事务中,查询俩次前后查询数据不一致的叫不可重复读
过程
- A事务第一次查询id=1的记录
- B事务更新id=1的记录并且提交
- A事务第二次查询id=1的记录,结果前后不一致
代码过程
事务A的客户端(数字代表执行顺序)
1. begin; ->客户端A开启事务
3. select * from account where id=1; ->客户端A第一次查询id=1的记录
6. select * from account where id=1; ->客户端A第二次查询id=1的记录
7. 前后查询不一致!
事务B的客户端
2. begin; ->客户端B开启事务
4. update account set money=money+1000 where id=1; ->客户端B更新id=1的记录
5. commit; ->客户端B提交数据
幻读
事务A按条件查询一个记录的时候该记录不存在
但是按照这个条件插入数据的时候会返回已经存在该数据。这种叫幻读
过程
- 事务A先查询数据a发现该数据不存在
- 事务B插入数据a并且提交
- 事务A插入数据a的时候返回说已经存在数据a
- 事务A查询时依然显示不存在数据a
代码过程
客户端A(数字代表执行顺序)
1. begin; ->客户端A开启事务
3. select * from account where id=3; ->假定不存在id=3的数据,事务A第一次查询id=3的数据
6. insert into account(id,name,money) values(3,'王五',3000); ->事务A插入id=3的数据,结果反馈说已经存在id=3的数据
7. select * from account where id=3; ->事务A继续查询id=3的数据,反馈不存在id=3的数据
客户端B
2. begin; ->客户端B开启事务
4. insert into account(id,name,money) values(3,'王五',3000); ->事务B插入id=3的数据
5. commit; ->事务B提交数据
并发事务的隔离级别
-
√代表会出现
-
×代表不会出现
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable Read(默认) | × | × | √ |
Serializable | × | × | × |
从read uncommitted--->serializable 隔离级别依次提高,性能依次下降。
语法
查询当前事务的隔离级别
select @@transaction_isolation;
设置事务的隔离级别
set [session/global] transaction isolation level [级别];
标签:事务,--,account,查询,提交,MYSQL,id,客户端 From: https://www.cnblogs.com/wdadwa/p/MYSQL_Learning_05.htmlsession代表对当前窗口有效,global代表对全部窗口有效