第13章:事务基础知识
#09-事务的基础知识#1.事务的完成过程
#步骤1:开启事务
#步骤2:一系列的DML操作
#....
#步骤3:事务结束的状态:提交的状态(COMMIT) 、 中止的状态(ROLLBACK)#2. 显式事务#2.1 如何开启? 使用关键字:start transaction 或 begin# start transaction 后面可以跟:read only / read write (默认) / with consistent snapshot #2.2 保存点(savepoint)
13.1 数据库事务概述
13.1.1 存储引擎支持情况
13.1.2 基本概念
13.1.3 事务的ACID特性
13.1.4 事务的状态
13.2 如何使用事务
13.2.1 显式事务
13.2.2 隐式事务
13.2.3 隐式提交数据的情况
#3. 隐式事务# 3.1 关键字:autocommit
#set autocommit = false;SHOW VARIABLES LIKE 'autocommit';#默认是ONUPDATE account SET balance = balance - 10 WHERE id = 1; #此时这条DML操作是一个独立的事务UPDATE account SET balance = balance + 10 WHERE id = 2; #此时这条DML操作是一个独立的事务#3.2 如何关闭自动提交?
#方式1:
SET autocommit = FALSE; #针对于DML操作是有效的,对DDL操作是无效的。UPDATE account SET balance = balance - 10 WHERE id = 1;UPDATE account SET balance = balance + 10 WHERE id = 2; COMMIT; #或rollback;#方式2:我们在autocommit为true的情况下,使用start transaction 或begin开启事务,那么DML操作就不会自动提交数据START TRANSACTION;UPDATE account SET balance = balance - 10 WHERE id = 1;UPDATE account SET balance = balance + 10 WHERE id = 2; COMMIT; #或rollback;
13.2.4 使用举例1:提交与回滚
#4. 案例分析
#SET autocommit = TRUE;
#举例1: commit 和 rollbackUSE atguigudb2;
#情况1:
CREATE TABLE user3(NAME VARCHAR(15) PRIMARY KEY);SELECT * FROM user3;BEGIN;
INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据
COMMIT;BEGIN; #开启一个新的事务
INSERT INTO user3 VALUES('李四'); #此时不会自动提交数据
INSERT INTO user3 VALUES('李四'); #受主键的影响,不能添加成功
ROLLBACK;SELECT * FROM user3;#情况2:
TRUNCATE TABLE user3; #DDL操作会自动提交数据,不受autocommit变量的影响。SELECT * FROM user3;BEGIN;
INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据
COMMIT;INSERT INTO user3 VALUES('李四');# 默认情况下(即autocommit为true),DML操作也会自动提交数据。
INSERT INTO user3 VALUES('李四'); #事务的失败的状态ROLLBACK;SELECT * FROM user3;#情况3:
TRUNCATE TABLE user3;SELECT * FROM user3;SELECT @@completion_type;SET @@completion_type = 1;BEGIN;
INSERT INTO user3 VALUES('张三');
COMMIT;SELECT * FROM user3;INSERT INTO user3 VALUES('李四');
INSERT INTO user3 VALUES('李四'); ROLLBACK;SELECT * FROM user3;
13.2.5 使用举例2:测试不支持事务的engine
#举例2:体会INNODB 和 MyISAMCREATE TABLE test1(i INT) ENGINE = INNODB;CREATE TABLE test2(i INT) ENGINE = MYISAM;#针对于innodb表
BEGIN
INSERT INTO test1 VALUES (1);
ROLLBACK;SELECT * FROM test1;#针对于myisam表:不支持事务
BEGIN
INSERT INTO test2 VALUES (1);
ROLLBACK;SELECT * FROM test2;
13.2.6 使用举例3:SAVEPOINT
#举例3:体会savepointCREATE TABLE user3(NAME VARCHAR(15),balance DECIMAL(10,2));BEGIN
INSERT INTO user3(NAME,balance) VALUES('张三',1000);
COMMIT;SELECT * FROM user3;BEGIN;
UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三';UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三';SAVEPOINT s1;#设置保存点UPDATE user3 SET balance = balance + 1 WHERE NAME = '张三';ROLLBACK TO s1; #回滚到保存点SELECT * FROM user3;ROLLBACK; #回滚操作SELECT * FROM user3;
13.3 事务隔离级别
13.3.1 数据准备
13.3.2 数据并发问题
13.3.3 SQL中的四种隔离级别
13.3.4 MySQL支持的四种隔离级别
13.3.5 如何设置事务的隔离级别
13.3.6 不同隔离级别举例
13.4 事务的常见分类
第14章:MySQL事务日志
14.1 redo日志
14.1.1 为什么需要REDO日志
14.1.2 REDO日志的好处、特点
14.1.2.1 好处
14.1.2.2 特点
14.1.3 redo的组成
14.1.4 redo的整体流程
14.1.5 redo log的刷盘策略
14.1.6 不同刷盘策略演示
14.1.6.1 流程图
14.1.6.2 举例
#10-事务日志USE atguigudb3;CREATE TABLE test_load(
a INT,
b CHAR(80)
)ENGINE=INNODB;#创建存储过程,用于向test_load中添加数据
DELIMITER//
CREATE PROCEDURE p_load(COUNT INT UNSIGNED)
BEGIN
DECLARE s INT UNSIGNED DEFAULT 1;
DECLARE c CHAR(80)DEFAULT REPEAT('a',80);
WHILE s<=COUNT DO
INSERT INTO test_load SELECT NULL,c;
COMMIT;
SET s=s+1;
END WHILE;
END //
DELIMITER;#测试1:
#设置并查看:innodb_flush_log_at_trx_commitSHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';#set GLOBAL innodb_flush_log_at_trx_commit = 1;#调用存储过程
CALL p_load(30000); #1min 28sec#测试2:
TRUNCATE TABLE test_load;SELECT COUNT(*) FROM test_load;SET GLOBAL innodb_flush_log_at_trx_commit = 0;SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';#调用存储过程
CALL p_load(30000); #37.945 sec#测试3:
TRUNCATE TABLE test_load;SELECT COUNT(*) FROM test_load;SET GLOBAL innodb_flush_log_at_trx_commit = 2;SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';#调用存储过程
CALL p_load(30000); #45.173 sec