MySQL之事物

て烟熏妆下的殇ゞ 提交于 2019-12-17 22:36:54

事物的简介

1.事物的概念
事物是一个操作序列,该序列中的多个操作要么都做,要么都不做
是MySQL5.5之后的存储引擎所支持

2.事物的特点
a.原子性
原子是自然界中最小的颗粒,具有不可再分的特点
事物中的所有操作可以看作是一个原子,要么全部执行,要么全不执行

b.一致性
事物执行的结果必须要保证数据库中数据的一致性

c.隔离性
隔离性指各个事物的操作是互不干扰的,任意一个事物的内部操作都对其他并发的事物都不能进行干扰

d.持久性
指事物一旦提交后,对数据库中数据做出的任何改变都会永久保存

事物的控制

1.开启事物
语法:start transaction |begin 开启一个新的事物

例如:开启新事物,完成张三给李四转账200
      start transaction;
      update account set balance=balance-200 where username='张三';
      update account set balance=balance+200 where username='李四';

注意:使用start transaction 开启一个新事物后,该事物就不会自动提交,必须手动提交

2.提交事物
语法:commit;

例如:开启新事物,完成张三给李四转账200,提交事物
      start transaction;
      update account set balance=balance-200 where username='张三';
      update account set balance=balance+200 where username='李四';
      commit;

3.回滚事物
语法:rollback;
注意:开启的事物,未提交时候可以回滚

例如:回滚事物
     start transaction;
      update account set balance=balance-200 where username='张三';
      update account set balance=balance+200 where username='李四';
     rollback;

事物的隔离级别

事物的隔离级别用于决定如何控制并发用户读写数据的操作

事物的隔离级别由低到高分为:

1.read uncommitted

指:读取未提交的数据内容

 例如:张三开启事物,进行转账操作 但不提交事物
         select * from account;
		 start transaction;
	 	update account set balance=balance-200 where username='张三';
	 	update account set balance=balance+200 where username='李四';
   
    设置事物隔离级别为read uncommitted
		set session transaction isolation level read uncommitted;

	查看事物隔离级别
		select @@transaction_isolation

	开始事物,查询表中的数据,可以查询到未提交的数据
		start transaction;
		select * from account;

   张三开始事物进行转账,但未提交事物,李四设置了隔离级别是read uncommitted,
   开启事物查询数据时就可以看到张三修改后的数据,如果张三现在做回滚操作,
   则李四看到的数据就是脏数据

2.read committed

指:读取提交的数据,该隔离级别下,所有事物只能看到其他事物已经提交的数据
该隔离级别解决了脏读的问题

 例如:设置李四窗口的隔离级别为  read committed
         set session transaction isolation level read committed;
      查看设置是否成功
         elect @@transaction_isolation
      开启事物读取数据
         start transaction;
	 	 select * from account;

      张三开启事物进行转账,不提交事物
        start transaction;
	 	update account set balance=balance-200 where username='张三';
	 	update account set balance=balance+200 where username='李四';

	  提交事物
	 	commit;

    李四设置了隔离级别是read committed,开启事物查询数据,
    张三开始事物进行转账,但不提交事物,李四查询数据时候没有看到转账的数据还是原来的数据,
    当张三提交了事物,李四查询数据时候可以看到提交后的数据,这样解决了脏读的问题,但是
    李四前后两次读取数据的结果不一致,则read committed不能解决重复读的问题

3.repeatable read

指:(可重复读)是MySQL默认的隔离级别

例如:
设置李四窗口的隔离级别为 repeatable read
	set session transaction isolation level repeatable read;
查看设置是否成功
    select @@transaction_isolation
开启事物读取数据
    start transaction;
	select * from account;

张三开启事物进行转账,不提交事物
     start transaction;
	 update account set balance=balance-200 where username='张三';
	 update account set balance=balance+200 where username='李四';
提交事物
	 commit;
     
   李四设置隔离级别 repeatable read,开启事物查询数据,
   张三开启事物进行转账,但不提交数据,李四查询数据,则看到还是原来的数据
   张三提交事物,李四查询数据,看到的数据还是原来的数据,查询的数据前后都是相同的数据
   则repeatable  read解决了不可重复读取的问题
    
2)幻读
	例如:
李四创建设置隔离级别 repeatable read
	set session transaction isolation level repeatable read;
查询是否设置隔离级别成功
    select @@transaction_isolation
开始事物查询数据
    start transaction;
	select * from account;

张三开始事物插入数据,并提交
	start transaction;
	insert into account(username,balance) values('王五',2000);
	commit;
 
测试:李四设置隔离级别 repeatable read,但是没有产生幻读问题,
因为:MySQL中InnoDB存储引擎使用(MVCC机制)
解决了repeatable read 下的幻读问题

例如: 
接着设置隔离级别为 read committed,演示
	set session transaction isolation level read committed;
查询是否设置隔离级别成功
    select @@transaction_isolation
开始事物查询数据
    tart transaction;
	select * from account;

张三开始事物插入数据,并提交
	start transaction;
	insert into account(username,balance) values('赵六',2000);
	commit;

设置隔离级别为read committed,开启事物查询数据,
另一个事物进行插入数据,并提交,在查询事物中再次查询,
结果可以查询到刚刚插入的数据则产生幻读

4.serializable
(可串行化)该隔离级别是最高的,同事花费也是最高的,性能最低,一般很少用
因为在该隔离级别下,事物按着顺序执行。

例如:
	set session transaction isolation level  serializable;
查询是否设置隔离级别成功
	select @@transaction_isolation
开始事物查询数据
	start transaction;
	select * from account;

开启事物,插入数据,并提交 (查看是否让插入)
	start transaction;
	insert into account(username,balance) values('孙琦',2000);
	commit;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!