赞
踩
事务是一组操作的集合, 它是一个不可分割的工作单位, 事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求, 即这些操作要么同时执行成功, 要么同时执行失败.
默认MySQL的事务是自动提交的, 也就是说, 当执行一行DML语句, MySQL会立即隐式的提交事务.
例如: 一组操作: 张三给李四, 转了1000元.
逻辑单元: 逻辑单元1: 张三账户余额 - 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却读到了数据, 此时读取的就脏数据.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。