Mysql事务特性
事务概念
事务可由一条sql或者一组sql组成。事务是访问并更新数据库中各种数据项的一个程序执行单元。
事务会把数据库从一种一致状态转换为另一种一致状态。在数据提交工作时,可以确保要么所有修改都已经保存了,要么所有修改都不保存。
事务需要满足ACID特性(不同厂商、mysql不同的存储引擎并非严格遵守ACID)。
ACID特性
原子性(atomicity)
事务是不可分割的工作单位,事务中的多个操作是一个整体,要么都做,要么都不做
一致性(consistency)
一致性指事务将数据库从一种一致状态转变为下一种一致状态。事务开始之前和结束之后,数据库的完整性约束并没有被破坏。如果事务中某个动作失败了,系统可以自动撤销事务并返回事务开始之前的状态。
隔离性(isolation)
多个事务之间彼此隔离,通过锁实现。一个事务对数据的操作在提交前是对其他事务隐藏的,隔离的。
持久性(durability)
事务一旦提交,其结果就是永久性的。就是发生宕机等故障,数据库也能将提交的数据恢复。mysql通过redo log实现。
原子性由redo log(重做日志)实现;
一致性由redo log和undo log(回滚段)实现;
持久性由redo log实现;
隔离性由锁实现。
事务隔离级别
大部分数据库都没有提供真正的隔离性,隔离性可以保证正确性但却无法保证性能。
RU(Read Uncommitted,读未提交)
一个事务可以读到其他事务已修改但尚未提交的数据,脏读。安全性最低,并发度(无锁)最高。
RC(Read Committed,读已提交)
一个事务中只可以读到已提交的数据,过程中如果数据被其他事务修改并提交,则当前事务再次读时,读到的是已修改后的数据,即不可重复读。
RR(Repeatable Read,可重复读)
一个事务只读取当前事务开始时提交的数据,过程中如果数据被其他事务修改并提交,则无影响;事务开始时不存在的数据,被其他事务提交后,当前事务可以读到,即幻读(不同数据库实现不同,mysql在RR隔离级别下使用next-key锁解决了幻读问题)。
Serializable(序列化/串行)
事务串行执行,安全性最高,并发度最低。
概念
脏读
脏数据指未提交的数据
脏读是当前事务读到了其他事务中未提交的数据,即读到了脏数据
不可重复读(侧重update)
在一个事务中对同一数据的两次/多次读取,读到的数据不一样,即不可重复读
幻读(侧重insert)
在一个事务中已经检查过不存在的记录,再次查询时却已存在
隔离性的实现-锁
行锁、间隙所、Next-key锁、Previous-key锁、页锁、意向锁、表锁、MDL(元数据)锁
行锁
顾名思义,在数据记录上加的锁,分为X锁和S锁。
间隙锁
锁住一段区间,range,不包括当前记录。
行锁+间隙锁=Next-key锁/Previous-key锁
包括当前记录
意向锁
行级锁分为X(写/独占)锁、S(读/共享)锁
一致性锁定读(加锁,根据情况,阻塞其他加锁请求)
通过加锁的方式
select ... for update; 加X锁
select ... lock in share mode; 加S锁
一致性非锁定读(不加锁,不阻塞)
mvcc(多版本并发控制,通过undo log实现)
死锁
死锁是指两个或者两个以上事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象
解决方案:超时、锁等待图
演示
准备
测试表建表sql
CREATE TABLE t_a (
id INT (10) NOT NULL,
content VARCHAR (10) NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB;
开启3个mysql终端,2个用来测试(以下统一使用t1,t2名称代替),1一个用来查看锁信息(以下统一使用info3名称代替)
修改事务隔离级别命令
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
隔离级别
RU隔离级别下脏读
设置事务隔离级别为RU
t1中开启事务,向t_a表中插入一条数据,不要提交
t2中开启事务,读t_a表的数据,读到了脏数据(未提交的数据)
如果t2中以此数据作为执行后续逻辑的判断条件,则可能会导致业务错误或者数据混乱。
t1中rollback
t2中再次查询,已经查不到了
RC隔离级别下无脏读
设置事务隔离级别为RC
t1中开启事务并向t_a表中插入一条记录,但是不提交
t2中开启事务,查询t_a表数据,发现不会查询出未提交的数据
提交t1中的事务
t2中再次查询,可以查询到已提交的数据,说明无脏读问题
RC隔离级别下不可重复读问题
先向t_a表中插入一条记录
t1中开启事务,并查询这条记录
t2中开启事务修改这条记录,并提交
t1中再次查询这条记录,发现数据不一致,也就是不可重复读
RR隔离级别下可重复读
设置事务隔离级别为RR
t1中开启事务,并查询t_a表中记录
t2中开启事务,修改表中记录,并提交
t1中再次查询t_a表中的记录,发现数据无变化,即可重复读
死锁
t1开启事务,对t_a的id为1的记录加X锁
t2中开启事务,对t_a的id为2的记录加X锁
t1中申请t_a的id为2的记录的X锁,被阻塞(t2中的事务正在持有锁)
t2中申请t_a的id为1的记录的X锁,报错,提示死锁
X锁、S锁
阻塞
t1中开启事务对t_a表中id为1的记录加X锁
t2中开启事务对t_a表中id为1的记录申请加S锁,被阻塞
info3中查询锁信息
MVCC
t1中开启事务对t_a表中id为1的记录加X锁
t2中开启事务读t_a表中id为1的记录,未阻塞
实例
上图中并发情况下,两个线程开启两个事务,同时执行到if代码行,则返回的结果都是true,会造成重复插入。
一般的解决方案有:
unique key
insert into ... select...
如下面的sql,
insert into t_a
select 3, '3'
from dual
where not exists (
select 0 from t_a where content = '3'
);
会对t_a表中content=3的记录加锁,阻塞其他插入content='3'的请求,从而避免重复插入
Mysql事务特性的更多相关文章
- Mysql 事务特性和隔离级别
事务的特性 原子性(Atomicity) 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)到 ...
- MySQL · 引擎特性 · InnoDB 事务子系统介绍
http://mysql.taobao.org/monthly/2015/12/01/ 前言 在前面几期关于 InnoDB Redo 和 Undo 实现的铺垫后,本节我们从上层的角度来阐述 InnoD ...
- 网络协议 finally{ return问题 注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池 C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务 DBUtils事务 ThreadLocal 事务特性 并发访问 隔离级别
1.1.1 API详解:注册驱动 DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 原因有2个: >导致驱动被注册2 ...
- 深入学习MySQL事务:ACID特性的实现原理
事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段.本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理. MySQL博大精深,文 ...
- MySQL事务及ACID特性
一.事物 1.定义:事务是访问和更新数据库的程序执行单元,事务中包含一条或者多条SQL语句,这些语句要么全部执行成功,要么都不执行. 在MySQL中,事务支持是在引擎层实现的,MySQL是一个支持多引 ...
- 一文说尽MySQL事务及ACID特性的实现原理
MySQL 事务基础概念 事务(Transaction)是访问和更新数据库的程序执行单元:事务中可能包含一个或多个 sql 语句,这些语句要么都执行,要么都不执行.作为一个关系型数据库,MySQL 支 ...
- MySQL InnoDB如何保证事务特性
如果有人问你"数据库事务有哪些特性"?你可能会很快回答出原子性.一致性.隔离性.持久性即ACID特性.那么你知道InnoDB如何保证这些事务特性的吗?如果知道的话这篇文章就可以直接 ...
- 个人MySQL的事务特性原理学习笔记总结
目录 个人MySQL的事务特性原理笔记总结 一.基础概念 2. 事务控制语句 3. 事务特性 二.原子性 1. 原子性定义 2. 实现 三.持久性 1. 定义 2. 实现 3. redo log存在的 ...
- MySQL 学习笔记(一)MySQL 事务的ACID特性
MySQL事务是什么,它就是一组数据库的操作,是访问数据库的程序单元,事务中可能包含一个或者多个 SQL 语句.这些SQL 语句要么都执行.要么都不执行.我们知道,在MySQL 中,有不同的存储引擎, ...
随机推荐
- jquery attribute选择器 语法
jquery attribute选择器 语法 作用:[attribute] 选择每个带有指定属性的元素.可以选取带有任何属性的元素(对于指定的属性没有限制). 语法:$("[attribut ...
- LA 2797
题目链接 题意:训练指南283页: #include <iostream> #include <cstdio> #include <cstring> #includ ...
- hdu 2553 八皇后问题 基础
题意:给你一个n*n的棋盘,要求放n个皇后: <span style="font-size:18px;">#include <iostream> #incl ...
- hdu_1059(多重背包)
多重背包的讲解: 多重背包问题https://blog.csdn.net/yandaoqiusheng/article/details/84782655 ; i <= n; i++) { int ...
- Android重写HorizontalScrollView模仿ViewPager效果
Android提供的ViewPager类太复杂,有时候没有必要使用,所以重写一个HorizontalScrollView来实现类似的效果,也可以当做Gallery来用 思路很简单,就是重写onTouc ...
- win10 exe如何添加或禁用开机自启动项
一.添加开机自启动 1,先打开存放自启动软件文件的文件夹 方法①:在文件搜索框中输入或粘贴以下地址: C:\ProgramData\Microsoft\Windows\Start Menu\Progr ...
- python学习之路(18)
返回函数 函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: >>> def a(* ...
- python学习之路(9)
函数的参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调 ...
- RabbitMq运行原理浅析
转载:https://blog.csdn.net/Evankaka/article/details/80977027 1.RabbitMq简介 AMQP,即Advanced Message Q ...
- 2019java第十二周课程总结
本周主要还是学习图形界面 各种容器使用方法 如下代码: package text10; import java.awt.*; import java.io.File; import javax.swi ...