SQL学习笔记08-- 事务

事务transaction:

   表示操作集合,不可分割,要么全部成功,要么全部失败

  事务的开始取决于一个DML语句
  事务的结束:
  1、正常的commit(使数据修改生效)或者rollback(将数据恢复到上一个状态)
  2、自动提交,但是一般情况下要将自动提交进行关闭,效率太低
  3、用户关闭会话之后,会自动提交事务
  4、系统崩溃或者断电的时候回回滚事务,也就是将数据恢复到上一个状态

  ▪ Commit: 表示事务成功地结束,此时告诉系统,数据库要进入一个新的正确状态, 
该事务对数据库的所有更新都以交付实施。每个Commit语句都可以看成是一个事
务成功的结束,同时也是另一个事务的开始。

 ▪ Rollback表示事务不成功的结束,此时告诉系统,已发生错误,数据库可能处在
不正确的状态,该事务对数据库的更新必须被撤销,数据库应恢复该事务到初始
状态。每个Rollback语句同时也是另一个事务的开始。


      一旦执行了commit语句,将目前对数据库的操作提交给数据库(实际写入DB),
以后就不能用rollback进行撤销。

insert into emp(empno,ename) values(7777,'asss');
commit;
select * from emp;

insert into emp(empno,ename) values(1234,'ghjn');
rollback;
select * from emp;

▪savepoint  保存点
   --当一个操作集合中包含多条SQL语句,但是只想让其中某部分成功,某部分失败,此时可以使用保存点
   --此时如果需要回滚到某一个状态的话使用 rollback to sp1;

--savepoint  保存点
--当一个操作集合中包含多条SQL语句,但是只想让其中某部分成功,某部分失败,此时可以使用保存点
--此时如果需要回滚到某一个状态的话使用 rollback to sp1;
delete from emp where empno = 1111;
delete from emp where empno = 2222;
savepoint sp1;
delete from emp where empno = 1234;
rollback to sp1;
commit;

事务的四个特性:ACID

1 原子性 Automicity:表示不可分割,一个操作集合要么全部成功,要么全部失败,不可以从中间做切分
2 一致性 consistency:最终是为了保证数据的一致性,当经过N多个操作之后,数据的状态不会改变(转账case)
                  从一个一致性状态到另一个一致性状态,也就是数据不可以发生错乱
3 隔离性 lsolation:各个事务之间相关不会产生影响,(隔离级别)
          严格的隔离性会导致效率降低,在某些情况下为了提高程序的执行效率,需要降低隔离的级别
          隔离级别:
            读未提交
            读已提交
            可重复读
            序列化
          数据不一致的问题:
            脏读
            不可重复读
            幻读
4 持久性 Durability:所有数据的修改都必须要持久化到存储介质中,不会因为应用程序的关闭而导致数据丢失

  四个特性中,哪个是最关键的?
     所有的特性中都是为了保证数据的一致性,所以一致性是最终的追求
     事务中的一致性是通过原子性、隔离性、持久性来保证的

锁的机制:
     为了解决在并发访问的时候,数据不一致的问题,需要给数据加锁
     加锁的同时需要考虑《粒度》的问题:
         操作的对象
            数据库
            表
            行
       一般情况下,锁的粒度越小,效率越高,粒度越大,效率越低 .
                            在实际的工作环境中,大部分的操作都是行级锁 .

  

mysql事务测试

1、打开mysql的命令行,将自动提交事务给关闭

--查看是否是自动提交 1表示开启,0表示关闭
select @@autocommit;
--设置关闭
set autocommit = 0;

2、数据准备

--创建数据库
create database tran;
--切换数据库 两个窗口都执行
use tran;
--准备数据
 create table psn(id int primary key,name varchar(10)) engine=innodb;
--插入数据
insert into psn values(1,'zhangsan');
insert into psn values(2,'lisi');
insert into psn values(3,'wangwu');
commit;

3、测试事务

--事务包含四个隔离级别:从上往下,隔离级别越来越高,意味着数据越来越安全
read uncommitted;   --读未提交
read commited;      --读已提交
repeatable read;    --可重复读
(seariable)         --序列化执行,串行执行
--产生数据不一致的情况:
脏读
不可重复读
幻读
隔离级别异常情况异常情况异常情况
读未提交脏读不可重复读幻读
读已提交 不可重复读幻读
可重复读  幻读
序列化   

 

4、测试1:脏读 read uncommitted

set session transaction isolation level read uncommitted;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
A:update psn set name='msb';
A:selecet * from psn
B:select * from psn;  --读取的结果msb。产生脏读,因为A事务并没有commit,读取到了不存在的数据
A:commit;
B:select * from psn; --读取的数据是msb,因为A事务已经commit,数据永久的被修改

5、测试2:当使用read committed的时候,就不会出现脏读的情况了,当时会出现不可重复读的问题

set session transaction isolation level read committed;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
--执行到此处的时候发现,两个窗口读取的数据是一致的
A:update psn set name ='zhangsan' where id = 1;
A:select * from psn;
B:select * from psn;
--执行到此处发现两个窗口读取的数据不一致,B窗口中读取不到更新的数据
A:commit;
A:select * from psn;--读取到更新的数据
B:select * from psn;--也读取到更新的数据
--发现B在同一个事务中多次读取数据出现不一致的情况

6、测试3:当使用repeatable read的时候(按照上面的步骤操作),就不会出现不可重复读的问题,但是会出现幻读的问题

set session transaction isolation level repeatable read;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
--此时两个窗口读取的数据是一致的
A:insert into psn values(4,'sisi');
A:commit;
A:select * from psn;--读取到添加的数据
B:select * from psn;--读取不到添加的数据
B:insert into psn values(4,'sisi');--报错,无法插入数据
--此时发现读取不到插入的数据,但是在插入的时候不允许插入,出现了幻读,设置更高级别的隔离级别即可解决

总结:

现在学习的是数据库级别的事务,需要掌握的就是事务的隔离级别和产生的数据不一致的情况

后续会学习声明式事务及事务的传播特性以及分布式事务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值