第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';#默认是ON
UPDATE 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 和 rollback
USE 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 和 MyISAM
CREATE 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:体会savepoint
CREATE 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_commit
SHOW 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