事务用于保证数据的一致性,InnoDB支持事务 MyISAM不支持事务
MySQL命令行的默认设置下,不开始事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作
#开始一个事务:
BEGIN 或 START TRANSACTION 或 SET AUTOCOMMIT=0
#SAVEPOINT 一个事务中可以有多个 SAVEPOINT
SAVEPOINT savepoint; // 声明一个 savepoint
ROLLBACK TO savepoint; // 回滚到savepoint
ROLLBACK;// 回滚所有
RELEASE SAVEPOINT savepoint; // 删除指定保留点
CREATE TABLE s3
(
id int,
name varchar(20)
);
START TRANSACTION;
//BEGIN 或 SET AUTOCOMMIT=0
SAVEPOINT a;
INSERT INTO s3 VALUES (1,'小明');
SAVEPOINT b;
INSERT INTO s3 VALUES (1,'小王');
ROLLBACK TO b;
SELECT * FROM s3;
脏读:A读取到B未提交的数据,然后B可能回滚数据,A读取的数据就是脏数据
不可重复读:A多次读取过程中,B将数据修改了,导致事务A在两次查询的数据不一致
幻读:一个事务在前后两次查询同一个范围的时候、后一次查询看到了前一次查询未看到的行
#事务的隔离级别
问题:脏读、不可重复读、幻读
隔离级别(4种) | 脏读 | 不可重复读 | 幻读 | 加锁读
-------------------------------------------
读未提交 | √ √ √ 不加
读已提交 | × √ √ 不加
可重复读 | × × √ 不加
可串行化 | × × × 加锁
InnoDB 存储引擎提供事务的隔离级别有:
READ UNCOMMITTED(读未提交)、READ COMMITTED(读已提交)、REPEATABLE READ(可重复读) 和 SERIALIZABLE(可串行化)
#查询当前隔离级别:默认REPEATABLE READ(可重复读)
SELECT @@transaction_isolation;
SHOW VARIABLES LIKE 'transaction_isolation';
修改全局隔离级别:
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
修改会话隔离级别:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
#READ UNCOMMITE(读未提交)测试:
(1).开启两个mysql命令窗口:A和B,A的隔离级别改为READ UNCOMMITE
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
(2).B开启事务,并插入数据
START TRANSACTION;
INSERT INTO s5 VALUES(3,'小明');
(3).A查询(读取到了窗口1没有commit的数据)
START TRANSACTION;
SELECT * FROM s5;
#READ COMMITTED(读已提交)测试
A:启动事务,此时数据为初始状态
B:启动事务,更新数据,但不提交
A:读数据,发现数据未被修改
(没有脏读)
B:提交事务
A:再次读取数据,发现数据已发生变化,A两次读取到的数据不一致,这就是所谓的“不可重复读”
#REPEATABLE READ(可重复读)测试
A:启动事务,此时数据为初始状态
B:启动事务,更新数据,但不提交
A:读取数据,发现数据未被修改
(没有脏读)
B:提交事务
A:再次读取数据,发现数据依然未发生变化
(可重复读)
B:插入一条新的数据,并提交
A:再次读取数据,发现数据依然未发生变化,读取不到新插入的行,这就是所谓的“幻读”
A:提交本次事务,再次读取数据,发现读取正常了
#SERIALIZABLE(可串行化)测试
A:启动事务,此时数据为初始状态
B:发现B此时进入了等待状态,原因是因为A的事务尚未提交,只能等待(B可能会发生等待超时)
A:提交事务
B:发现插入成功
ACID:原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则
隔离性:隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
#存储引擎
SHOW ENGINES;
InnoDB:Supports transactions, row-level locking, and foreign keys
MyISAM:表级锁、不支持外键和事务
MEMORY:Hash based, stored in memory, useful for temporary tables(被mongodb、redis等NOSQL替代)
#视图
视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据,作为一个select语句保存在数据字典中的
CREATE TABLE s8
(
id INT,
`name` VARCHAR(32),
`password` VARCHAR(32)
);
INSERT INTO s8 VALUES (1,'小明','password1'), (2,'小王','password2'),(3,'小张','password3');
CREATE TABLE s9
(
id INT,
`address` VARCHAR(32),
`email` VARCHAR(32)
);
INSERT INTO s9 VALUES (1,'重庆','123@163.com'), (2,'上海','456@163.com');
#创建视图
CREATE VIEW view_test AS SELECT s8.id,`name`,email FROM s8,s9 WHERE s8.id = s9.id;
#修改视图
ALTER VIEW view_test AS SELECT s8.id,`name`,email FROM s8 LEFT JOIN s9 ON s8.id = s9.id;
#查询视图
SELECT * FROM view_test;
#删除视图
DROP VIEW view_test;
#基表的数据变化会反应到视图,视图由简单查询生成时可以通过视图进行更新操作
UPDATE s8 SET name = '小强' WHERE id = 1;
SELECT * FROM view_test;