zl程序教程

您现在的位置是:首页 >  IT要闻

当前栏目

MySQL——锁和事务管理

2023-02-18 16:34:37 时间
MySQL的锁 Lock

保证数据安全的一种手段。防止数据文件同时被多个用户同时修改,从而造成数据的破坏。

MySQL锁的分类:
  • 读锁:S锁,例如给一个表加了读锁以后,大家都能读表里面的内容(只能读不能改)

  • 写锁:X锁。加了写锁以后,只有自己才能访问,其他人不行(读和写都不行)

读锁和写锁是不兼容了,加了写锁就不能加读锁。

MySQL锁的范围:
  • 表级锁:myisam吗,整个表全部都加锁,例如改其中一条记录会把整个表都锁起来。

  • 行级锁:innodb,只锁定自己正在修改的那条记录。

实现锁这个功能:
  • 显式实现:手动设置

  • 隐式实现:通过存储引擎自动添加

手动实现锁的功能
加锁:
lock tables tb_name lock_type

lock_type:
READ   #读锁
WRITE  #写锁
解锁:
unlock lock_name
查询锁:
select claue
加全局读锁:

关闭正在打开的表(清除查询缓存),通常在备份前加全局读锁来保证数据的只读性。

添加全局读锁:
FLUSH TABLES  WITH READ LOCK 

解锁:
unlock tables

MySQL事务 Transactions:一组原子性的SQL语句
事务的特性:ACID
  • A:atomicity 原子性;事务中的所有操作要么全部成功执行,要么全部失败后回滚

  • C:consistency 一致性;数据库总是从一个一致性状态转换为另一个一致性状态。

  • I:Isolation隔离性;事务执行操作的期间相互之间是隔离的,互不影响。
    事务在执行期间产生的数据叫做脏数据(没有确定下来的数据)

  • D:durability持久性;一旦事务提交,其所做的修改会永久保存于数据库中

事务的生命周期
  1. 刚开始数据库处于初始阶段

  2. 开启一个事务

  3. 进行相关操作(事务没有结束前都属于脏数据)

  4. 提交或者取消事务

  5. 一旦提交以后数据就存到了数据库,取消事务就回到了初始状态。

MySQL事务的管理:
  • 启动事务:
三个都表示事务的开始 
BEGIN

BEGIN WORK

START TRANSACTION
mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
+-----+---------------+-----+--------+
5 rows in set (0.00 sec)

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

mysql> delete from teachers where tid = 5 ;
Query OK, 1 row affected (0.00 sec)

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
+-----+---------------+-----+--------+
4 rows in set (0.00 sec)

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

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
+-----+---------------+-----+--------+
5 rows in set (0.00 sec)

  • 结束事务:

只用DML这种SQL语言才能撤销。其他的不能撤销

#提交,相当于vi中的wq保存退出
COMMIT

#回滚,相当于vi中的q!不保存退出
ROLLBACK
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            0 |
+--------------+
1 row in set (0.00 sec)

mysql> delete from teachers;
Query OK, 4 rows affected (0.00 sec)

mysql> select * from teachers;
Empty set (0.00 sec)

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

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
+-----+---------------+-----+--------+
4 rows in set (0.00 sec)
  • 自动提交功能:更改变量autocommit的值
 set autocommit={1|0},默认是1
 
 mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

 MySQL每一条独立的DML语句就是一个完整的事务。执行操作后就默认自动提交了。
  • 查看事务:
死锁的概念:

两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态

事务的隔离级别:
隔离级别查看:
select @@tx_isolation;


这个变量支持四个值:

READ UNCOMMITTED:能看到脏数据

READ COMMITTED:不可重复度

REPEATABLE READ:幻读

SERIALIZABLE:可串行化
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
隔离级别比较
隔离级别 脏读 不可重复读 幻读 加读锁
读未提交 可以出现 可以出现 可以出现
读提交 不允许出现 可以出现 可以出现
可重复读 不允许出现 不允许出现 可以出现
序列化 不允许出现 不允许出现 不允许出现

例如:可重复读,一个事务将数据改变以后,即使提交了,另一个事务里面也不能看到事务发生的变化,只能看到刚开启事务时数据的状态。

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

mysql> insert into teachers(name,age,gender) values('bob',24,'M');
Query OK, 1 row affected (0.00 sec)

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
|   6 | bob           |  24 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)

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

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
|   6 | bob           |  24 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)

这个事务在执行过程中,永远看到的是自己刚开启事务时数据的状态。
但是这个数据早就发生改变了,这就是可重复读(幻读)。
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
+-----+---------------+-----+--------+
5 rows in set (0.00 sec)

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
+-----+---------------+-----+--------+
5 rows in set (0.00 sec)

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
+-----+---------------+-----+--------+
5 rows in set (0.00 sec)

例如:不可重复读:只要数据发生了改变(已经提交),就能看到数据发生的改变

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


mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
|   6 | bob           |  24 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)

mysql> update teachers set age=25 where tid=6;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
|   6 | bob           |  25 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)

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

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
|   6 | bob           |  24 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
|   6 | bob           |  25 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)

mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | tom           |  30 | M      |
|   6 | bob           |  24 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)