数据库
事务的隔离级别
SQL标准定义了4类隔离级别:
1.read uncommitted 读取未提交内容:实际应用很少使用,会出现 脏读,不可重复读,幻读;
2.read committed 读取已提交:一般数据库的默认隔离级别,会出现 不可重复读,幻读
3.repeatable read 可重复读:MySQL的默认隔离级别,SQL标准定义下,该隔离级别下可能会出现幻读。但MySQL的InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
4.serializable 可串行化:最高隔离级别,强制事务排序,在每个读的数据行上加S锁,。可能会出现大量超时和锁竞争。效率低下。
*** 注:不可重复读侧重点在于修改原有数据,幻读侧重点在于插入新数据 ***
全局/会话 隔离级别
1.MySQL设置事务隔离级别分为全局(Glabal)和回话(Session).其中回话级别优先级更高。
例如:全局隔离级别为可重复读会话级别为未提交读的事务A可以查询到其他所有隔离级别的事务未提交的数据,反之,非未提交读的事务不能查询到其他事务未提交的数据。
InnoDb MVCC。
MySQL在使用了InnoDB引擎时,给每行数据增加两个隐藏字段(创建版本号,过期版本号)来实现MVCC.每次开始一个新的事务时,会为每个事务分配一个事务版本号(该过程为并发安全过程)。
可简单理解为:
1.insert时,赋值创建版本号=当前事务版本号。
2.update时,将旧数据复制一份,并将旧数据的过期版本号设置为当前事务版本号,新数据的创建版本号为当前事务版本号。
3.delete时,赋值删除版本号=当前事务版本号。
事务中索引和非索引字段的区别
非索引字段:非索引字段默认加锁到整表中。
索引字段:加锁到 处于索引范围内的数据行。
快照读和当前读
快照读:读取是快照版本,也即当前事务版本对应的快照版本。普通的 select 语句
当前读: 读取最新版本。select for … update,update、delete、insert、select … lock in share mode.
常用命令(mysql-8.0.15)
1.查询当前Session的隔离级别
select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| READ-UNCOMMITTED |
+-------------------------+
1 row in set (0.00 sec)
2.查询Global的隔离级别
``
select @@global.transaction_isolation;
+--------------------------------+
| @@global.transaction_isolation |
+--------------------------------+
| REPEATABLE-READ |
+--------------------------------+
1 row in set (0.00 sec)
``
3.设置当前的隔离级别
# session 可以省略,默认session(session、global), read uncommitted : 隔离级别(read uncommitted、read uncommitted、repeatable read、repeatable read)
set session transaction isolation level read uncommitted;
4.开启/结束 事务
# 开启事务 默认每条语句为一个事务
start transaction;
#结束事务(提交/回退)
commit/rollabck
# 取消自动提交(1:自动提交,0:非自动提交,需手动commit)
set autocommit=0