Mysql的事务

1.基本概念

     事务本质是一组SQL操作,事务中的语句要么全部执行成功,或者全部执行失败。

2.如何保证一个事务:四个特性(ACID)

原子性 (Automic)

     表示事务是操作的最小单元。整个事务的操作,要么全部成功,要么全部失败。

一致性 (consistency)

     数据库总是从一个状态转换成另一个状态。

当事务中间执行错误时,事务会回滚到执行事务之前的状态。如果整个事务执行成功,才能成为成功的状态。

隔离性 (isolation)

     一般来说,一个事务在提交操作之前对其他事务是不可见的。

在事务中的操作完成提交之后,其他的事务才能看到当前对数据库的修改。当然这只是一般状态,因为隔离级别的不同,可能会存在差异。

持久性 (durablity)

     一个事务执行成功,其所对数据库所进行的修改会永久的保存到数据库中。

3.Mysql的事务操作

开始事务
  start transaction;
set autocommit=0;
提交事务 commit;
回滚事务 rollback;
 - mysql 默认不开始事务,需要手动启动事务

 - 每一步数据修改都直接生效

 - 查看事务是否开启

        show variables like 'autocommit';

4.事务的可见性控制:隔离级别

     不同数据库及数据引擎可能会有不同,以innodb数据库引擎为准

四种隔离级别:

  • READ UNCOMMITED(读未提交) 事务中的修改,即使没有提交,其他事务也能看到;
  • READ COMMITED (读已提交) 一个事务只能看到提交的事务做出的修改;
  • REPEATED READ (可重复读) 保证多次读取同样的记录是一致的。MYSQL的默认隔离级别
  • SERIALIZABLE (序列化) 强制让事务串行执行,会给读取的每一行数据都加上锁,所以会造成锁竞争,出现超时情况。

隔离级别的设置:

set tx_isolation='READ-UNCOMMITTED';
set tx_isolation='read-committed';
set tx_isolation='repeatable-read';
set tx_isolation='serializable'; 查看隔离级别
select @@transaction_isolation

访问冲突情况

隔离级别 访问冲突现象
read-uncommitted 脏读,幻读,不可重复读
read-committed 幻读,不可重复读
repeatable-read 幻读
serializable 序列化,完全隔离(同一个表,只能一个事务处理)

脏读:

     可以读取其他事务未提交的数据

客户端1 客户端2
set tx_isolation='read-uncommitted'; set tx_isolation='read-uncommitted';
rollback;begin; rollback;begin;
Insert into tb1(name)values('bb'); Select * from tb1;
Update tb1set name='a'where id=1; Select * from tb1;
rollback; Select * from tb1;

不可重复读:

     其他事务对当前事务查询范围数据进行了的修改,在其他事务提交后,查询到的是修改后的数据。因为在其他事务提交之前和其他事务提交之后查询的结果不一致,因此也就是不可重复读。

客户端1 客户端2
select @@transaction_isolation
set transaction_isolation='read-committed'
select @@transaction_isolation
set transaction_isolation='read-committed'
begin begin
select * from temp (图一)
update temp set name='zhangsan' where name='zs'
select * from temp
commit
select * from temp(图二)
commit

图一:



图二:

幻读:

幻读,又叫做幻行。指在当前事务查询的范围内,其他事务进行了增删操作,当再次查询的时候就会出现幻行的情况。

客户端1 客户端2 客户端3
select @@transaction_isolation
set transaction_isolation='repeatable-read'
select @@transaction_isolation
set transaction_isolation='repeatable-read'
select @@transaction_isolation
set transaction_isolation='repeatable-read'
begin begin begin
select * from temp(图一)
delete from temp where name ='lisi'
commit
select * from temp(图二)
insert into temp (id,name)values(uuid(),'xiaohong');
commit
select * from temp(图三)
commit

图一:

图二:

图三:

5.事务的资源竞争:锁

5.1 Mysql的锁和引擎有关系
  • innodb默认使用的是行级锁
一个事务修改一行数据未提交时, 该行数据会被锁定,不允许其他事务修改
  • myisam 默认使用的是表级锁
5.2 死锁

出现场景:当两个事务或多个事务在统一资源上占用,并请求对象占用的资源,造成了恶行循环;

事务一
start transaction
update temp set username='zhangsan' where username='zs'
update temp set username='ls' where username='lisi' 事务二
start transaction
update temp set username='lsj' where username='lisi'
update temp set username='zhangsanfeng' where username='zs'
5.2 几种常见的数据库锁
乐观锁
乐观锁,通常不是数据库自带,通过自己实现;
实现的过程一般为:
例子:
在修改信息当前,判断versions,和之前存储的versions编号进行比对,看是否一致
1.查询要修改数据的标志(sign)
select name,sign from temp where id='666'
2.修改要调整的数据,判断sign是否和之前的查询数据一直,如果一直则更新;
update temp set name='wangwu',sign=sign+1 where id='666'and sign='之前的sign'
悲观锁

在整个数据处理过程中,将数据处于锁定状态

悲观锁的实现:

1. 自动提交模式要关闭
set autocommit = 0;
当执行一个sql时,数据库立即执行; 2. 开启事务
begin;/begin work;/start transaction; 3. 查询要操作数据的信息
SELECT * FROM TB WHERE CD FOR UPDATE FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据会等其他数据执行完毕后再执行 4.数据进行插入操作等
insert into t_orders (id,goods_id) values (null,1); 5.更新插入数据列状态
update t_goods set status=2; 6.提交SQL执行
commit;/commit work;
手动对需要执行的SQL进行提交;

不过我们需要注意一些锁的级别,MySQL InnoDB默认Row-Level Lock,所以只有「明确」地指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。

明确指定了主键,并且有该数据,row lock
console1:
BEGIN;
SELECT * FROM city WHERE id='1' FOR UPDATE
  |id|name|state|
|:--|---:|:--:|
|1|美国|0|
console2:
BEGIN;
SELECT * FROM city WHERE id='1' FOR UPDATE

查询被阻塞;

报错:error:1205

Lock wait timeout exceeded; try restarting transaction

明确指定主键,若查无此数据,无lock
console1:查询结果为空;
console2:查询结果为空,查询无阻塞,说明console1没有对数据执行锁定
主键不明确,table lock
console1:查询正常
BEGIN ;
SELECT * FROM city WHERE id !='3' FOR UPDAT;
id name state
1 美国 0
2 新加坡 0
console2:查询被阻塞,说明console1把表锁住了
BEGIN;
SELECT * FROM city WHERE id ='1' FOR UPDATE

共享锁

console1: 查询没有问题
BEGIN;
select * from city WHERE ID='1' LOCK IN SHARE MODE
console2:查询阻塞报错;
select * from city WHERE ID='1'
console2:查询没有问题
select * from city WHERE ID='1' LCOCK IN SHARE MODE 用的共享锁,可以查询同一行数据,但是不能进行insert,update等操作,因为这些操作会单独在次进行锁的判断

排它锁

console1:查询无误
BEGIN;
SELECT * FROM CITY WHERE ID='1' FOR UPDATE
console2:阻塞状态
SELECT * FROM CITY WHERE ID='1'
console2:阻塞状态
SELECT * FROM CITY WHERE ID='1' FOR UPODATE

共享锁和排它锁更像是悲观锁的一个分类;

参考博客:https://blog.csdn.net/puhaiyang/article/details/72284702

数据库基础02-MYSQL的事务的更多相关文章

  1. 重新学习MySQL数据库8:MySQL的事务隔离级别实战

    重新学习Mysql数据库8:MySQL的事务隔离级别实战 在Mysql中,事务主要有四种隔离级别,今天我们主要是通过示例来比较下,四种隔离级别实际在应用中,会出现什么样的对应现象. Read unco ...

  2. 数据库基础之Mysql

    数据库的简介 数据库 数据库(database,DB)是指长期存储在计算机内的,有组织,可共享的数据的集合.数据库中的数据按一定的数学模型组织.描述和存储,具有较小的冗余,较高的数据独立性和易扩展性, ...

  3. 渣渣小本求职复习之路每天一博客系列——数据库基础(MySQL)(5)

    前情回顾:昨天学习了MySQL中索引的设计与使用,还了解了一些常见的SQL注入攻击的手段以及防范方法,一般来说,在面试的时候如果不是要求比较高,基本就够用了. 今天碰见一个拿了TP-LINK的offe ...

  4. 【原创】数据库基础之Mysql(1)常用命令

    1 创建用户 CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 比如 create user 'test_user'@'%' identi ...

  5. 【原创】数据库基础之Mysql(2)主从库配置

    一 安装 # wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm# yum -y insta ...

  6. 【原创】数据库基础之Mysql(3)mysql删除历史binlog

    mysql开启binlog后会在/var/lib/mysql下创建binlog文件,如果手工删除,则下次mysql启动会报错: mysqld: File './master-bin.000001' n ...

  7. 26.MySQL数据库基础

    MySQL数据库基础 目录 MySQL数据库基础 数据库的概念 数据 表 数据库 数据库的管理系(DBMS) 数据库系统 访问数据库的流程 数据库系统发展史 当今主流数据库介绍 关系数据库 关系数据库 ...

  8. 【Python全栈-数据库】数据库基础

    数据库的简介 数据库 数据库(database,DB)是指长期存储在计算机内的,有组织,可共享的数据的集合.数据库中的数据按一定的数学模型组织.描述和存储,具有较小的冗余,较高的数据独立性和易扩展性, ...

  9. Mysql基础(六):索引、数据库备份、锁和事务、慢查询优化、索引命中相关

    目录 数据库05 /索引.数据库备份.锁和事务.慢查询优化.索引命中相关 1. 什么是索引 2. 索引的原理 3. 索引的数据结构(聚集索引.辅助索引) 4. 索引操作 5. 索引的两大类型hash与 ...

  10. MySQL数据库基础学习

    MySQL基础知识 ----------- MySQL数据库简介 内存:一断电数据就没有了---------数据库:可以实现数据的持久化存储,有完整的管理系统管理,方便查询--------- DB:数 ...

随机推荐

  1. java实现第四届蓝桥杯马虎的算式

    马虎的算式 题目描述 小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了. 有一次,老师出的题目是:36 x 495 = ? 他却给抄成了:396 x 45 = ? 但结果却很戏剧性,他的答 ...

  2. 如何在交互式环境中执行Python程序

    相信接触过Python的小伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行.命令行窗口运行.开发工具上运行等,其中在不同的操作平台上还互不相同.今天,小编讲些Pyth ...

  3. LiveCharts 提示框(DataTooltip)百分比一直为0.00%解决办法

    LiveCharts 提示框(DataTooltip)百分比一直为0.00%解决办法 问题描述:在使用LiveCharts 开源图标库的时候,使用CartesianChart类图表,当Series为L ...

  4. 如何让json_encode不转义斜杠

    当服务器返回一些数据时需要返回一些地址,但是默认的json_code是会对 / 转义成 \/ 的处理... 解决办法: 1. 正则替换: echo str_replace("\\/" ...

  5. dubbo traceId透传实现日志链路追踪(基于Filter和RpcContext实现)

    一.要解决什么问题: 使用elk的过程中发现如下问题: 1.无法准确定位一个请求经过了哪些服务 2.多个请求线程的日志交替打印,不利于查看按时间顺序查看一个请求的日志. 二.期望效果 能够查看一个请求 ...

  6. Python类中装饰器classmethod,staticmethod,property,

    @classmethod 有的时候在类中会有一种情况,就是这个方法并不需要使用每一个对象属性 因此 这个方法中的self参数一个完全无用的参数,使用classmethod class A: __cou ...

  7. C#数据结构与算法系列(二):稀疏数组(SparseArray)

    1.介绍 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组.    稀疏数组的处理方法是: 1.记录数组一共有几行几列,有多少个不同的值    2.把具有不同值的元素的 ...

  8. [TopCoder]Seatfriends

    题目   点这里看题目. 分析   可以想到用 DP 解决.   由于把空位放到状态里面太麻烦了,因此我们单独将 " 组 " 提出来进行 DP .   \(f(i,j)\):前\( ...

  9. Java8新特性之方法引用

    <Java 8 实战>学习笔记系列 定义 方法引用让你可以重复使用现有的方法定义,并像Lambda一样传递它,可以把方法引用看作针对仅仅涉及单一方法的Lambda的语法糖,使用它将减少自己 ...

  10. Java容器相关知识点整理

    结合一些文章阅读源码后整理的Java容器常见知识点.对于一些代码细节,本文不展开来讲,有兴趣可以自行阅读参考文献. 1. 思维导图 各个容器的知识点比较分散,没有在思维导图上体现,因此看上去右半部分很 ...