首页 > 数据库 >[Mysql-事务]

[Mysql-事务]

时间:2024-07-30 19:27:42浏览次数:16  
标签:事务 隔离 记录 幻读 -- Session Mysql

目录

事务是什么:

简单事务实现举例:

事务ACID原则:

事务隔离性

事务的隔离级别:

锁分类:


事务是什么:

        事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内 的所有SQL都将被取消执行。

简单事务实现举例:

        就像现实中两个人转账,转账方的操作成功,但是收钱方并没有收到钱。这个时候我们应该要实现当无论哪一方的操作失败,数据库中的金额都保持不变。

-- 创建一个bank表,字段为姓名和金额。

create table bank(
    bid int primary key auto_increment,
    bname varchar(10),
    bmoney decimal(20,2)
);

-- 添加数据

insert into bank(bname,bmoney) values('收钱',5);
insert into bank(bname,bmoney) values('转账',100000000000000);

-- 事务的操作
-- 1. 关闭自动提交
set autocommit = 0;
-- 2. 开始事务
start transaction;
-- 3. 一组sql语句
update bank set bmoney = bmoney-1000 where bname='转账';
update bank set bmoney = bmoney+1000 where bname='收钱';

-- 4. 结束事务(判断)
    -- 提交
    commit;
    -- 回滚
    rollback;
-- 5. 开启自动提交
set autocommit = 1;

事务ACID原则:

原子性、一致性、隔离性、持久性

事务的原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。

REDO LOG 称为 重做日志 ,提供再写入操作,恢复提交事务修改 的页操作,用来保证事务的持久性。

UNDO LOG 称为 回滚日志 ,回滚行记录到某个特定版本,用来保 证事务的原子性、一致性。

事务隔离性

什么是事务的隔离性:为了让不同的事务之间相互不存在干扰,就需要对事务的操作进行隔离, 事务的隔离性也就是将操作同一个数据的事务相互分离,让操作之间分开有序的执行

用什么方式实现事务的隔离性: 通常数据库里都是采用锁的机制,保证事务之间的隔离性

事务并发问题: 在事务并发执行的时候,如果不进行事务隔离,那么就会产生脏写、脏读、 重复读、幻读的问题。

事务的隔离级别:

  1. READ_UNCOMMITTED 读未提交     会产生脏读、 重复读、幻读

  2. READ_COMMITTED 读提交(不可重复读)  会产生重复读、幻读

  3. REPEATABLE_READ 重复读    会产生幻读

  4. SERIALIZABLE 串行化

    每个隔离级别都针对事务并发问题中的一种或几种进行解决,事务级别越高,解决的 并发事务问题也就越多,同时也意味着加的锁就越多,所以性能也会越差。

mysql默认隔离级别:不可重复读

innodb不会出现幻读问题,通过mvcc机制

锁分类:

基于锁的属性分类:共享锁(读锁、S锁)、排他锁(写锁,X锁)。

基于锁的粒度分类:表锁、行锁(记录锁、间隙锁、临键锁)。

基于锁的状态分类:意向共享锁、意向排它锁。

附一些事务常见面试题:

1. 事务并发会出现的问题:

        脏写( Dirty Write ) 对于两个事务 Session A、Session B,如果事务Session A 修改了 另⼀个 未提交 事务Session B 修改过 的数据,那就意味着发⽣了 脏写

        脏读( Dirty Read ) 对于两个事务 Session A、Session B,Session A 读取 了已经被 Session B 更新 但还 没有被提 交 的字段。 之后若 Session B 回滚 ,Session A 读取 的内容就是 临时且⽆效 的。 Session A和Session B各开启了⼀个事务,Session B中的事务先将studentno列为1的记录的name 列更新 为'张三',然后Session A中的事务再去查询这条studentno为1的记录,如果读到列name的值为'张 三',⽽ Session B中的事务稍后进⾏了回滚,那么Session A中的事务相当于读到了⼀个不存在的数据,这 种现象 就称之为 脏读 。

        不可重复读( Non-Repeatable Read ) 对于两个事务Session A、Session B,Session A 读取 了⼀个字段,然后 Session B 更新 了该字 段。 之后 Session A 再次读取 同⼀个字段, 值就不同 了。那就意味着发⽣了不可重复读。 我们在Session B中提交了⼏个 隐式事务 (注意是隐式事务,意味着语句结束事务就提交了),这 些事务 都修改了studentno列为1的记录的列name的值,每次事务提交之后,如果Session A中的事务都可 以查看 到最新的值,这种现象也被称之为 不可重复读 。

        幻读( Phantom ) 对于两个事务Session A、Session B, Session A 从⼀个表中 读取 了⼀个字段, 然后 Session B 在 该表中 插 ⼊ 了⼀些新的⾏。 之后, 如果 Session A 再次读取 同⼀个表, 就会多出⼏⾏。那就意味着发⽣了幻 读。 Session A中的事务先根据条件 studentno > 0这个条件查询表student,得到了name列值为'张 三'的记录; 之后Session B中提交了⼀个 隐式事务 ,该事务向表student中插⼊了⼀条新记录;之后Session A 1. 事务并发会出现的问题 2 中的事务 再根据相同的条件 studentno > 0查询表student,得到的结果集中包含Session B中的事务新插⼊ 的那条记 录,这种现象也被称之为 幻读 。我们把新插⼊的那些记录称之为 幻影记录 。

2. 幻读:

幻读是指在⼀个事务中多次执⾏相同的查询,但是第⼆次查询返回的结果集中包含了第⼀次查询时 不存在的记录。这通常发⽣在其他事务插⼊了新的记录,⽽这些新记录在第⼀个查询之后、第⼆个 查询之前被插⼊到数据库中。

为了避免幻读问题,可以采取以下⼏种⽅法:

        1. 使⽤事务隔离级别: 重复读(Repeatable Read): 设置事务隔离级别为重复读可以避免幻读。在这个隔离级 别下,MySQL使⽤间隙锁(Gap Locks)来锁定查询结果集之间的间隙,防⽌其他事务 插⼊新的记录。 串⾏化(Serializable): 设置事务隔离级别为串⾏化可以完全避免并发问题,但可能会降 低性能,因为所有事务都会按顺序执⾏。

        2.使用⾏级锁: 在执⾏更新或删除操作时,可以显式加锁来防⽌其他事务插⼊新的记录。

        3.间隙锁: InnoDB存储引擎使⽤间隙锁来锁定查询结果集之间的间隙,防⽌其他事务插⼊新 的记录。

        4.使⽤悲观锁: 在事务开始时就对需要访问的数据加锁,直到事务结束。这种⽅法可以有效避免幻读,但 也可能导致锁等待和性能下降。

        5.使⽤乐观锁: 假设并发冲突较少,事务在提交时才检查是否有冲突。通常通过版本号或时间戳来实现。 虽然这种⽅法不能完全避免幻读,但可以减少锁的使⽤,提⾼并发性能。

        6.使⽤事务的SAVEPOINT和ROLLBACK: 在事务中使⽤保存点(SAVEPOINT)和回滚(ROLLBACK)功能,可以在发现幻读后回 滚到保存点,重新执⾏查询。

        7. 使⽤数据库约束: 使⽤唯⼀约束或主键约束来防⽌插⼊重复的记录,从⽽避免幻读。 

3. MySQL的MVCC:

MySQL的多版本并发控制(MVCC)是⼀种⽤于实现事务隔离的技术,它允许多个事务在同⼀时 刻对同⼀数据进⾏操作⽽不互相阻塞。MVCC通过维护数据的多个版本来实现这⼀点,每个事务看 到的数据版本是基于该事务开始时的数据版本。 

标签:事务,隔离,记录,幻读,--,Session,Mysql
From: https://blog.csdn.net/2301_78794952/article/details/140791857

相关文章

  • 【MySQL(锁篇)】深入MySQL锁机制:从全局到行级,解锁数据库性能瓶颈(上:MySQL锁介绍、表级锁
    文章目录MySQL(锁篇)-全局锁、表锁、行锁(记录锁、间隙锁、临键锁、插入意向锁)、意向锁、SQL加锁分析、死锁产生原因与排查一条Update语句MySQL锁介绍1锁分类2全局锁表级锁1什么是表级锁?2表读锁、写锁2.1表锁相关命令2.2表锁演示3元数据锁3.1元数据锁介绍3.2元......
  • 【MySQL(锁篇)】深入MySQL锁机制:从全局到行级,解锁数据库性能瓶颈(下:行锁分析实战、死锁原
    文章目录MySQL(锁篇)-全局锁、表锁、行锁(记录锁、间隙锁、临键锁、插入意向锁)、意向锁、SQL加锁分析、死锁产生原因与排查行锁分析实战1读已提交RC1.1组合一:ID是主键1.2组合二:ID唯一索引1.3组合三:ID非唯一索引1.4组合四:ID无索引2可重复读RR2.1组合五:ID主键2.2组......
  • MySQL安装出现初始化错误
    在安装末端初始化数据库的时候有概率会出现unknownvariable‘mysqlx_port=0.0‘.,这种情况一般是在卸载过MySQL的机器上出现:解决办法如下: 1/删除Data文件夹,一般默认在C:\ProgramData\MySQL\MySQLServer8.0\Data;2/修改my.ini文件:mysqlx-port=0.0改为mysqlx-port=33060;3/重......
  • MySQL存储引擎MyISAM和InnoDB
    目录1.1MySQL存储引擎1.1.1什么是存储引擎1.1.2MySQL5.7支持的引擎1.1.3如何选择MySQL引擎1.1.4可以根据以下的原则来选择MySQL存储引擎 1.1.5MyISAM和InnoDB的区别1.MyISAM存储引擎2.InnoDB存储引擎1.1.6关于MyISAM与InnoDB选择使用1.1.7.修改默认......
  • Linux中,MySQL存储引擎
    存储引擎在数据库中保存的是一张张有着千丝万缕关系的表,所以表设计的好坏,将直接影响着整个数据库。而在设计表的时候,最关注的一个问题是使用什么存储引擎。MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种都使用不同的存储机制、索引技巧、锁定水......
  • MySQL 备份与恢复
    目录4.1MySQL数据库备份概述4.1.1数据备份的重要性4.1.2数据库备份类型1.从物理与逻辑的角度分类2.从数据库的备份策略角度分类4.1.3常见的备份方法1.物理冷备份2.专用备份工具mysqldump或mysqlhotcopy3.通过启用二进制日志进行增量备份4.通过第三方工具备份......
  • MySQL 数据库初体验
    1.1数据库简介1.1.1使用数据库的必要性可以结构化存储大量的数据信息,方便用户进行有效的检索和访问。可以有效地保持数据信息的一致性、完整性,降低数据几余。可以满足应用的共享和安全方面的要求。1.1.2数据库的基本概念1、数据    描述事物的符号记录称为数据......
  • mysql中的mysqladmin
    mysqladmin是一个MySQL服务器命令行工具,它由DatabaseAdministrators执行一些基本的命令诸如更改root密码、监控mysql进程、重新加载权限、检查服务器状态等任务。mysqadmin常用命令#mysqladmin帮助mysqladmin--help#连接mysql,-h[hostipaddress]mysqladmin-h......
  • MySQL 学习笔记 进阶(存储过程 下,存储函数,触发器,锁 上)
    存储过程 存储过程-if判断语法IF条件1THEN......ELSEIF条件2THEN......ELSE......ENDIF; 存储过程-参数 用法CREATEPROCEDURE存储过程名称([IN/OUT/INOUT参数名参数类型])BEGIN--SQL语句END; 存储过程-c......
  • Mysql设置自增ID
    1、创建新表时设置ID自增:CREATETABLEyour_table_name(idINTNOTNULLAUTO_INCREMENT,nameVARCHAR(255),PRIMARYKEY(id));2、为现有表添加自增ID:ALTERTABLEyour_table_nameADDCOLUMNidINTNOTNULLAUTO_INCREMENTPRIMARYKEY;3......