我眼中的数据库

MySQL之事务隔离级别

2019-07-13  本文已影响0人  一岁一枯荣啊
先看个风景图,调整下心情吧

本文我们将围绕一下几点进行分析

一 :什么是事务?

数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。—— 维基百科

说白了,数据库的事物就是由一步或几步数据库操作序列组成逻辑执行单元,这个单元要么全部成功执行,要么全部不执行。事物是在mysql引擎层面支持的,那么Mysql有哪些类型的存储引擎呢?都支持事物么?
对于>=MySQL 5.5的版本,默认的存储引擎是InnoDB。在5.5版本之前,MySQL的默认存储引擎是MyISAM。

如何查看默认存储引擎的方式

查看 默认的存储引擎可以使用 show engines命令

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
如何查看单张表使用的存储引擎?
mysql> SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE, ENGINE from information_schema.TABLES where TABLE_NAME = 'user_info';
+--------------+------------+------------+--------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE |
+--------------+------------+------------+--------+
| olatest      | user_info  | BASE TABLE | InnoDB |
+--------------+------------+------------+--------+
1 row in set (0.01 sec)

如何修改MySQL的默认存储引擎
    修改my.cnf,在配置文件里面

增加参数default-storage-engine,然后重启数据库服务。

修改单张表的存储引擎
mysql> ALTER TABLE user_info ENGINE = MyISAM;
Query OK, 1000001 rows affected (7.02 sec)
Records: 1000001  Duplicates: 0  Warnings: 0

mysql> SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE, ENGINE from information_schema.TABLES where TABLE_NAME = 'user_info';
+--------------+------------+------------+--------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE |
+--------------+------------+------------+--------+
| olatest      | user_info  | BASE TABLE | MyISAM |
+--------------+------------+------------+--------+
1 row in set (0.00 sec)

扯的有点远。。。回正题,事物ACID四大特性也是必须要了解的

为什么事物需要隔离性?

如果事务之间不是互相隔离的,可能将会很多的问题 脏读、不可重复读、幻读

*** 脏读与不可重复读有点懵逼?脏读 vs 不可重复读
------1.脏读是某事务读取了另外一事务未提交的数据
------2.不可重复读是读取了其他事务已经提交成功的数据
*** 不可重复读与幻读有点懵逼?不可重复读 vs 幻读
------1.不可重复读针对一条数据
------2.幻读是比不可重复读更高级别的不可重复,针对一些数据

PS:不可重复读其实是正常现象,比如我们在银行取钱的时候,显示的5000块,但是点击提现的时候,卡里的钱自己败家媳妇前几秒取走了买包了,
提示余额不足取不出来这想来也是正常~

事务的隔离级别有哪几种?怎么设置?

上面出现这问题场景,肯定是要得到解决的,那么我们就需要设置数据库的隔离级别
SQL标准定义了4种隔离级别的具体规则,用来限定事务内的哪些改变对其他事物是可见的,哪些是不可见的。
当然隔离级别越高,系统性能开销将更大

这 4 种隔离级别,性能依次降低,安全性依次提高
(读未提交) ------> (读已提交) ------> (可重读) ------> (串行化)

  1. 读未提交: 别人的事务未提交我也可以读到
  2. 读已提交: 别人的事务必须提交我才可以读
  3. 可重读 : 别人的事务提交了,我也不读
  4. 串行化 : 别人的事务未提交,我也改不了数据

查看并设置Mysql隔离级别

1.REPEATABLE READ:可重复读(默认)
2.READ COMMITTED:提交读
3.READ UNCOMMITTED:未提交读
4.SERIALIZABLE:串行读

注意!!!!在网上看了很多博客都是用的
select @@tx_isolation;
然后我在终端操作一直提示 

mysql> select @@tx_isolation;
ERROR 1193 (HY000): Unknown system variable 'tx_isolation'

其实是因为在8.0+就已经抛弃了这样的查询方法官网有说明:
[https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html) 
具体可参考下图
mysql8.0.png

//最新的查看全局的事务隔离级别
//第1种方法
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+
1 row in set (0.00 sec)

//第2种方法
mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)

设置MysQL的事务隔离级别
语法

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
  {
       REPEATABLE READ
     | READ COMMITTED
     | READ UNCOMMITTED
     | SERIALIZABLE
   }

GLOBAL:设置全局的事务隔离级别
SESSION:设置当前session的事务隔离级别,如果语句没有指定GLOBAL或SESSION,默认值为SESSION

mysql>  set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.01 sec)

mysql> show variables like 'transaction_isolation';
+-----------------------+------------------+
| Variable_name         | Value            |
+-----------------------+------------------+
| transaction_isolation | READ-UNCOMMITTED |
+-----------------------+------------------+
1 row in set (0.01 sec)

mysql> 

Spring 事物隔离级别于Mysql隔离级别的关系?

Spring会在事务开始时,根据你程序中设置的隔离级别,调整数据库隔离级别与你的设置一致。

上一篇 下一篇

猜你喜欢

热点阅读