MySQL 原理篇html
MySQL 索引机制sql
MySQL 执行计划详解session
MySQL5.5 及之后版本的默认存储引擎使用的是 InnoDB,接下来针对事务的讲解都是基于 InnoDB 存储引擎的。
事务:数据库操做的最小工做单元,是做为单个逻辑工做单元执行的一系列操做; 事务是一组不可再分割的操做集合(工做逻辑单元)。
典型事务使用场景:转帐
update user_account set balance = balance - 1000 where userID = 3; update user_account set balance = balance + 1000 where userID = 1;
MySQL 开启事务:
/* BEGIN / START TRANSACTION --手工 COMMIT / ROLLBACK --事务提交或回滚 SET SESSION autocommit = ON/OFF --设定会话级别事务是否自动开启 */
MySQL 默认是开启事务的,经过 SHOW VARIABLES like 'autocommit';
能够查看 MySQL 的事务开启状况。
BEGIN;
或者 START TRANSACTION;
命令,改成手动提交事务,执行完 SQL 语句后,须要经过 COMMIT
命令提交事务,或者经过 ROLLBACK
命令回滚事务。COMMIT
命令提交事务,或者经过 ROLLBACK
命令回滚事务。JDBC 编程:
connection.setAutoCommit(boolean);
测试命令:
SHOW VARIABLES like 'autocommit'; /* autocommit为ON */ update teacher set name ='seven' where id =1; insert teacher (name,age) value ('james',22); delete from teacher where name = 'james'; /* autocommit为ON如何开启事务 */ BEGIN; START TRANSACTION; update teacher set name ='seven' where id =1; insert teacher (name,age) value ('james',22); delete from teacher where name = 'james'; COMMIT; ROLLBACK; /* 将autocommit改为OFF */ set session autocommit = OFF; update teacher set name ='seven' where id =1; insert teacher (name,age) value ('james',22); delete from teacher where name = 'james'; COMMIT; ROLLBACK;
原子性(Atomicity):最小的工做单元,整个工做单元要么一块儿提交成功,要么所有失败回滚。
一致性(Consistency):事务中操做的数据及状态改变是一致的,即写入资料的结果必须彻底符合预设的规则,不会由于出现系统意外等缘由致使状态的不一致。
隔离型(Isolation):一个事务所操做的数据在提交以前,对其余事务的可见性设定(通常设定为不可见)。
持久性(Durability):事务所作的修改就会永久保存,不会由于系统意外致使数据的丢失。
参考(原子性和一致性的区别是什么?)这篇博文,讲了一下原子性和一致性的区别。
好比 user 表中有一条用户数据,执行了以下操做:
这个时候,事务A中查询出的 id=1 的数据,age 的值是16仍是18?
好比 user 表中有一条用户数据,执行了以下操做:
这个时候,事务A两次查询出的 id=1 的数据,age 的值是16仍是18?
好比在 user 表中执行了以下操做:
这个时候,事务A两次查询出的数据,数量是1条仍是2条?
SQL92 ANSI/ISO标准:http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
Read Uncommitted(未提交读) --未解决并发问题
事务未提交对其余事务也是可见的,脏读(dirty read)
Read Committed(提交读) --解决脏读问题
一个事务开始以后,只能看到本身提交的事务所作的修改,不可重复读(non repeatable read)
Repeatable Read(可重复读) --解决不可重复读问题
在同一个事务中屡次读取一样的数据结果是同样的,这种隔离级别未定义解决幻读的问题
Serializable(串行化) --解决全部问题
最高的隔离级别,经过强制事务的串行执行
事务隔离级别 |
脏读 |
不可重复读 |
幻读 |
未提交读(Read Uncommitted) |
可能 |
可能 |
可能 |
已提交读(Read Committed) |
不可能 |
可能 |
可能 |
可重复读(Repeatable Read) |
不可能 |
不可能 |
对 InnoDB 不可能 |
串行化(Serializable) |
不可能 |
不可能 |
不可能 |
事务隔离级别的并发能力:未提交读 > 已提交读 > 可重复读 > 串行化
InnDB 引擎默认的事务隔离级别是可重复读(Repeatable Read),在该级别中它把幻读的问题也解决了。InnDB 中事务隔离级别经过锁、MVCC 实现。
经过以下语句查看 InnoDB 的默认事务隔离级别:
/* 全局、当前会话的隔离级别 */ SELECT @@global.tx_isolation, @@tx_isolation;
经过以下语句设置 InnoDB 的事务隔离级别:
/* 设置全局隔离级别 */ set global transaction isolation level read committed; /* 设置当前会话的隔离级别 */ set session transaction isolation level read committed;
接下来咱们来测试一下 InnoDB 的默认事务隔离级别(Repeatable Read)是否解决了脏读、不可重复读、幻读的问题。
数据准备:
CREATE TABLE `user` ( `id` int(11) NOT NULL, `name` varchar(32) NOT NULL, `age` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; insert into `user` (`id`, `name`, `age`) values('1','Ada','16');
开启两个 MySQL 客户端,模拟事务A和事务B的操做,执行步骤以下:
图中的数字是执行步骤,经过下图能够看出事务A的执行结果是16,InnDB 的默认事务隔离级别完美的解决了脏读的问题。
开启两个 MySQL 客户端,模拟事务A和事务B的操做,执行步骤以下:
图中的数字是执行步骤,经过下图能够看出事务A两次的执行结果都是16,没有受事务B更新操做的影响,InnDB 的默认事务隔离级别完美的解决了不可重复读的问题。
开启两个 MySQL 客户端,模拟事务A和事务B的操做,执行步骤以下:
图中的数字是执行步骤,经过下图能够看出事务A两次的执行结果都是一条数据,没有受事务B新增操做的影响,InnDB 的默认事务隔离级别完美的解决了幻读的问题。
原文出处:https://www.cnblogs.com/yinjw/p/11880568.html