(Mysql 六)事务

1.存储引擎的使用

2.为什么用事务

3.事务的特点

4.脏读,幻读,可重复读和不可重复读

5.隔离级别

6.事务的控制语句


1.存储引擎的使用:

mysql 中,存储引擎使用 InnoDB,对事务有良好的支持(mysql默认的引擎就是InnoDB)

查看表是什么引擎:SHOW TABLE STATUS WHERE name = ‘table_name’   \G;  

mysql> show table status where name='zje'\G;
*************************** 1. row ***************************
           Name: zje
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 8
 Avg_row_length: 2048
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2017-02-13 14:26:22
    Update_time: 2017-02-13 18:07:18
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.02 sec)

上面可以看到引擎为InnoDB


创建表时把表设置为 InnoDB引擎:create table aaa(id int)engine = innodb;   //创建aaa表,引擎设置为innodb

2.为什么用事务:

事务是应用多多个用户使用数据库的情况的。以银行为例。

有用户A要把500块钱转给用户B,那就存在几个步骤:

1.检查A的账户是否多于500块钱。

2.A的账户减少500块钱。

3.B的账户增加500块钱

但万一 A扣钱之后,B加钱之前,系统崩溃了,那就会造成500块无端端没了。这就需要用到事务。


3.事务的特点:

事务必须拥有 4个特性,分别是:ACID

A(原子性):表示一个事务里面的操作要么全部执行成功,要么全部回滚,不可以只成功执行一部分。

C(一致性):一个事务的执行不应该破坏数据库的完整性约束。

I(隔离性):不同事务之间的行为互不影响,但实际上不同事务也会有一定的影响,影响的程度在于隔离级别,隔级别度等等说。

D(持久性):事务提交后的数据,即使系统崩溃,也不会丢失。


4.脏读,幻读,可重复读和不可重复读

脏读:表示一个事务读取了另一个未提交的事务修改的数据,而这个数据是有可能回滚的。


幻读:表示当某个事务在读取某个范围的值时,有另一事务在这个范围内插入一个新记录时,之前的事务再次读取这个范围的值,会读到插入的新纪录。

   然后mysql的InnoDB引擎的间隙锁已经解决了幻读问题。


不可重复读:当事务A在查看id为1的score数据(select  score from  table where id = 1),例如score = 100,事务A暂时还没提交,若此时事务B对id=1的,score数据进行修改(update table set score=0  where id =1),把score修改为0(提交),此时事务A若再次读取score数据,读到的不是100,而是会显示0。


可重复读:与不可重复读相反,当事务A读取数据时,事务B修改了数据,事务A再读,还是会是原本的数,绝不会读到被修改的数据。但若是事务B把一个数据的id改为1,

    事务A虽看不到变化,但如果事务A插入新数据,并把id号设置为1,则会发生错误,因为id=1的数据已经存在。


5.隔离级别

隔离级别是对应事务的隔离性,一共有4个隔离级别,分别表示不同的隔离程度:

1.READ UNCOMMITTED(未提交读)

2.READ COMMITTED(提交读)

3.REPEATABLE READ(重复读)

4.SERIALIZABLE(可串行化)


1.READ UNCOMMITTED(未提交读)

容易发生脏读,属于隔离级别比较低的,一般不常用

2.READ COMMITTED(提交读)

不会出现脏读。事务A在读数据时,恰巧事务B在修改数据,但必须先等到事务B提交后,事务A才能读到被B修改的数据。但这就形成了不可重复读。


3.REPEATABLE READ(可重复读)

此隔离级别解决了不可重复读的问题。变成可重复读。这是mysql默认的隔离级别。


4.SERIALIZABLE(可串行)

此隔离级别是隔离程度最高的。事务在执行中的时候,就不能读数据。唯有没有任何事务处理数据时,用户才能读数据。


注意:隔离级别越高,并发效果越低。可串行隔离级别是没有并发的。


6.事务的控制语句

autocommit:

autocommit是mysql中的一个全局变量,用于控制事务是否自动提交。默认情况给下autocommit=1,表示是自动提交执行,即会自动加上commit语句。

例如 select * from zje; 回车后,就会自动加上commit提交。而我们要写拥有多个SQL语句的事务,就要显式地开始一个事务。或设置autocommit=0 表示事务要手动加上commit才会提交执行。

在autocommit=0的情况下,对数据的修改,只要不commit,那么数据的修改自己看到,当commit了之后,才会对数据库的数据进行真正的修改。

查看 autocommit 的值: select @@autocommit;

修改 autocommit的值:set @@autocommit = 0;  //或set @@autocommit = 1;


显式开始事务:

四个重要语句:

START  TRANSACTION; 或 BEGIN;   //开始事务

ROLLBACK; //回滚事务

SAVEPOINT     p1; //设置一个断点,名为p1,可以用ROLLBACK TO savepoint  p1;来回滚到p1处。

COMMIT; //提交事务


在mysql命令行默认的形式是,提交一个SQL语句,就会自动执行commit,相当于一个SQL语句就是一个事务,因为默认下 autocommit = 1;如果我们需要开始一个由多条

SQL语句组成的事务,则要显示地开始事务。如果是autocommit=0,则不需要START TRANSATION /BEGIN ,在输入commit之前,全部的SQL语句都是一个事务。


下面给出当 autocommit=1的情况下事务的使用:

mysql> select *from eva;
Empty set (0.03 sec)

mysql> begin;
Query OK, 0 rows affected (0.01 sec)

mysql> insert eva(id,value) values(1,100);
Query OK, 1 row affected (0.01 sec)

mysql> rollback;
Query OK, 0 rows affected (0.03 sec)

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from eva;
Empty set (0.01 sec)

上面的代码在执行事务时,往eva表插入了一个数据,但是又执行了rollback,所以再次select eva表时,还是空表

mysql> select * from eva;
Empty set (0.01 sec)

mysql> begin;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into eva(id,value) values(1,100);
Query OK, 1 row affected (0.01 sec)

mysql> insert into eva(id,value) values(2,200);
Query OK, 1 row affected (0.01 sec)

mysql> commit;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from eva;
+------+-------+
| id   | value |
+------+-------+
|    1 |   100 |
|    2 |   200 |
+------+-------+
2 rows in set (0.01 sec)
上面的代码并没有用rollback回滚,所以当commit提交事务时,就会把修改提交到mysql,进行真正的数据插入。


mysql> select * from eva;
+------+-------+
| id   | value |
+------+-------+
|    1 |   100 |
|    2 |   200 |
+------+-------+
2 rows in set (0.01 sec)

mysql> begin;
Query OK, 0 rows affected (0.02 sec)

mysql> delete from eva where id = 1;
Query OK, 1 row affected (0.01 sec)

mysql> savepoint p1;
Query OK, 0 rows affected (0.01 sec)

mysql> delete from eva where id=2;
Query OK, 1 row affected (0.02 sec)

mysql> rollback to savepoint p1;
Query OK, 0 rows affected (0.01 sec)

mysql> commit;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from eva;
+------+-------+
| id   | value |
+------+-------+
|    2 |   200 |
+------+-------+
1 row in set (0.02 sec)
上面的代码展示了 savepoint 的使用,由代码可以看出,eva表一开始是有2组数据的,分别是id=1和id=2的数据。

而随后删除id=1的数据后,我们加入了一个断点p1,然后再删除id=2的数据,然后回滚到p1处,可以看出最后commit后查看eva表,只删除了id=1的数据。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值