事务是一组操作的集合, 它是一个不可分割的工作单位, 事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求, 即这些操作要么同时执行成功, 要么同时执行失败.
默认MySQL的事务是自动提交的, 也就是说, 当执行一行DML语句, MySQL会立即隐式的提交事务.
例如: 一组操作: 张三给李四, 转了1000元.
逻辑单元2: 李四账户余额 + 1000元
* 事务详解: 例如: 一组操作: 张三给李四, 转了1000元. 逻辑单元: 逻辑单元1: 张三账户余额 - 1000元 逻辑单元2: 李四账户余额 + 1000元 */ -- 1.创建表 # 1.1 创建account表 create table account( id int primary key auto_increment, name varchar(10) not null , money int not null ); # 1.2 向表中插入数据 insert into account values (null, '张三', 2000),(null, '李四', 2000); # 1.3 查询数据 select * from account; # 1.4 恢复到初始金额(张三李四账户金融各2000元) update account set money = 2000 where name in('张三', '李四');
查询结果:
例如:
# (转账操作) -- 2.对于当前来说, 每一条SQL都是一个事务, # 2.1 查询张三账户余额 select * from account where name = '张三'; # 2.2将张三账户余额 - 1000元 update account set money = money-1000 where name = '张三'; 程序输出异常... # 此处设置程序输出异常, 则程序执行失败,张三的余额为1000元, 但是李四余额还是2000元. # 为了解决这种程序异常的问题,我们就需要将张三和李四的转账操作放置在一个 事务中执行. # 2.3 将李四的账户余额+1000元 update account set money = money + 1000 where name = '李四';
执行结果:
为了解决程序异常的, 我们需要将该程序相关的事务封装到一个事务中执行.
方式一: 通过关闭事务的自动提交, 通过commit去提交, 通过rollback去回滚事务.
格式:
查看/设置事务的提交方式: select @@autocommit; # 1 是自动提交 set @@autocommit = 1; # 0 是手动提交
提交事务: commit;
回滚事务(当事务执行过程中出现异常时, 可以回滚事务, 回到执行前的状态): rollback ;
-- 3. 将MySQL中的自动提交设置为手动提交 -- 查看/设置事务的提交方式 (注意: 此处设置的是会话参数, 只针对当前窗口有效) select @@autocommit; # 1 是自动提交 set @@autocommit = 1; # 0 是手动提交 # 3.1 查询张三账户余额 select * from account where name = '张三'; # 3.2将张三账户余额 - 1000元 update account set money = money-1000 where name = '张三'; # 3.3 将李四的账户余额+1000元 update account set money = money + 1000 where name = '李四'; -- 提交事务: commit; -- 回滚事务(当事务执行过程中出现异常时, 可以回滚事务, 回到执行前的状态) rollback ;
方式二: 可以通过指令来开启事务, 通过commit去提交, 通过rollback去回滚事务.
格式:
开启事务 有两种命令: start transaction 或 begin
提交事务: commit;
-- 4. 方式二: 将MySQL中的自动提交设置为手动提交 # 开启事务 (有两种命令: start transaction 或 begin) start transaction ; # 4.1 查询张三账户余额 select * from account where name = '张三'; # 4.2将张三账户余额 - 1000元 update account set money = money-1000 where name = '张三'; # 4.3 将李四的账户余额+1000元 update account set money = money + 1000 where name = '李四'; # 提交事务: commit; # 回滚事务(当事务执行过程中出现异常时, 可以回滚事务, 回到执行前的状态) rollback ;
就是A事务和B事务同时操作一张数据表而引发的问题,
一个事务读到另外一个事务还没有提交的数据
一个事务先后读取同一条记录, 但两次读取的数据不同, 称之为不可重复度.
一个事务按照条件查询数据时, 没有对应的数据行, 但是在插入数据时, 有发现这样数据已经存在, 好像出现了''幻影'.'
提示: 就是解决事务并发所引发的问题
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed (Oracle默认) | × | √ | √ |
Repeatable Read (MySQL默认) | × | × | √ |
Serializable | × | × | × |
select @@transaction_isolation;
# 设置当前会话窗口的事务隔离级别 set session transaction isolation level {Read uncommitted | Read committed | Repeatable Read | Serializable} # 设置全局的事务隔离级别 set global transaction isolation level {Read uncommitted | Read committed | Repeatable Read | Serializable}
事务B更新没有提交, 但是事务A却读到了数据, 此时读取的就脏数据.