事务的概述
什么是事务
- 事务指逻辑上的一组操作,组成这组操作的单元要么全部成功,要么全部失败。
操作: zs向李四转账100元 zs:1000,ls:1000
组成单元: zs钱-100, ls钱+100
操作成功: zs钱900,ls钱1100
操作失败: zs钱1000,ls钱1000
不可能发生: zs钱900,ls钱1000; zs钱1000,ls钱1100
事务的作用
- 保证一组操作全部成功或者失败。
MYSQL进行事务管理
自动管理事务(mysql默认):
- 一条sql语句就是一个事务(mysql默认自动开启事务,自动提交事务)
-- 账户表
create table account(
id int primary key auto_increment,
name varchar(20),
money double
);
insert into account values (null,'zs',1000);
insert into account values (null,'ls',1000);
insert into account values (null,'ww',1000);
-- 场景: zs向ls转账100元
-- zs钱-100 ls钱+100
-- zs钱-100
update account set money = money - 100 where name = 'zs';
-- ls钱+100
update account set money = money + 100 where name = 'ls';
-- 如果是自动事务管理,在java程序中,如果zs钱-100之后发生了异常,ls钱+100的代码就执行不了了,那
么就会出现zs钱变成900,ls钱依然还是1000
-- 查看mysql是否是自动提交事务
show variables like '%commit%';
手动管理事务
方式一:
手动开启事务的方式
- start transaction;开启事务
- commit;提交
- rollback;回滚
-- 场景: zs向ls转账100元
-- 没有异常
-- 开启事务
start transaction;
-- zs钱-100
update account set money = money - 100 where name = 'zs';
-- ls钱+100
update account set money = money + 100 where name = 'ls';
-- 提交事务
commit;
-- 有异常
-- 开启事务
start transaction;
-- zs钱-100
update account set money = money - 100 where name = 'zs';
-- 可能在这里发生异常
-- ls钱+100
update account set money = money + 100 where name = 'ls';
-- 回滚事务
rollback;
-- 提交事务或者回滚事务都会结束事务
方式二:
- 设置MYSQL中的自动提交的参数
- 查看MYSQL中事务是否自动提交
show variables like '%commit%';
- 设置自动提交的参数为OFF
set autocommit = 0;-- 0:OFF 1:ON
注意
- 建议手动开启事务, 用一次 就开启一次,用完了,就关闭
- 开启事务之后, 要么commit, 要么rollback
- 一旦commit或者rollback, 当前的事务就结束了
- 回滚到指定的回滚点, 但是这个时候事务没有结束的
事务特性和隔离级别
事务特性:
- 原子性( Atomicity )原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
- 一致性(Consistency)事务前后数据的完整性必须保持一致.
- 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
- 隔离性(Isolation)事务的隔离性是指多个用户并发操作数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。 简单来说: 事务之间互不干扰
如果不考虑隔离性,会引发下面的问题:
- 脏读:一个事务读取到了另一个事务中尚未提交的数据。
- 不可重复读:一个事务中两次读取到的数据内容不一致,要求的是一个事务中多次读取时事务是一样的,这是事务UPDATE时引发的问题。
- 幻读:一个事务中两次读取的事务数量不一致,要求在一个事务多次读取的数据是一致的,这是insert或dalate时引发的问题。
- 幻读可以看MySql是如何解决幻读的具体介绍以及解决方式
事务的隔离级别:
如下图:
设置事务隔离级别:
set session transaction isolation level 隔离级别;
查询当前事务隔离级别:
select @@tx_isolation;