首页 > 数据库 >mysql中的事务

mysql中的事务

时间:2024-07-28 21:57:49浏览次数:14  
标签:事务 读取 幻读 数据库 Session mysql 隔离

 一、事务的定义

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

特点:一个事务中如果有一个数据库操作失败,那么整个 事务的所有数据库操作都会失败,数据库数据就会 回滚到该事务开始之前的状态。 

限制:MySQL数据库中仅InnoDB和BDB类型的数据库表 支持事务。

二、事务的特性

原子性:意味着数据库中的事务执行是作为原子粒度即不可再分,整个语句要么执行要么不执行。

一致性:即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

隔离性:事务的执行是互不干扰的,一个事务不可能看到其他事务运行时中间某一时刻的数据。

持久性:意味着在事务完成以后 ,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。 

三、MySQL实现事务的方法

四、MySQL实现事务的步骤 

-- 事务的操作
-- 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;

四、事务的原子性、一致性、持久性 

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

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

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

五、事务的隔离性

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

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

六、MySql中的锁 

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

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

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

七、事务的隔离级别

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

事务的隔离级别: 1. READ_UNCOMMITTED 读未提交

                              2. READ_COMMITTED 读提交(不可重复读)

                              3. REPEATABLE_READ 可重复读

                              4. SERIALIZABLE 串行化

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

八、事务的隔离级别解决的问题

1.READ_UNCOMMITTED

  • 事务读取:不加锁
  • 事务写入:加写锁解决问题:脏写
  • 存在问题:脏读,不可重复读、幻读

2.READ_COMMITTED

  • 事务读取:加读锁(每次select完成都会释放读锁)事务写入:加写锁
  • 解决问题:脏写、脏读
  • 存在问题:不可重复读、幻读。

3.REPEATABLE_READ

  • 事务读取:加读锁(每次select完不会释放锁,而是事务结束后才释放)(如果是Mysql的innodb还会加间隙锁)。
  • 事务写入:加写锁
  • 解决问题:脏写、脏读、不可重复读,幻读(如果是Mysql的innodb则已解决)存在问题:幻读(如果是Mysql的innodb则不存在)。

4.SERIALIZABLE


        不管读取还是修改所有的事务串行化执行,一个事务的执行必须等其他事务结束。
 

九、事务并发时出现的问题 

1.脏写( Dirty Write )

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

2.脏读( 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中的事务相当于读到了一个不存在的数据, 这种现象 就称之为 脏读 。 

3.不可重复读( Non-Repeatable Read )

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

4.幻读( Phantom )

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

十、InnoDB的MVCC

MVCC (Multiversion Concurrency Control),多版本并发控制。顾名思义,MVCC 是通过数据行的多个 版 本管理来实现数据库的 并发控制 。这项技术使得在InnoDB的事务隔离级别下执行 一致性读 操作有 了保 证。换言之,就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值, 这样 在做查询的时候就不用等待另一个事务释放锁。 MVCC 的实现依赖于:隐藏字段、Undo Log、Read View。 InnoDB就是通过MVCC机制解决可重复读中的幻读问题。

标签:事务,读取,幻读,数据库,Session,mysql,隔离
From: https://blog.csdn.net/m0_68041576/article/details/140672878

相关文章

  • 团队内部技术分析-数据库事务和锁
    背景目前团队是学习型的团队,除了完成日常业务工作需求外,还需要考虑做一些相应的输出。与团队共同成长,同时也是驱动自己学习总结的一种很好的方式。分享内容什么是数据库事务?数据库的锁?不同的数据库隔离级别的加锁方式?如何避免锁等待死锁?什么是数据库事务MySQL常用的存储......
  • mysql系列:sql执行原理
    sql执行流程当谈到数据库管理系统(DBMS)的核心功能时,SQL执行引擎无疑是其中最关键的部分之一。SQL执行引擎负责将我们编写的结构化查询语言(SQL)转化为实际可以操作数据库的物理操作序列。它不仅仅是一个简单的语法解析器,更是一种复杂的软件模块,涉及到查询优化、执行计划生成、......
  • MYSQL如何实现将数据同步到ES?
    MYSQL如何实现将数据同步到ES?这个问题既要考虑到既能保持数据一致性,又能够保证实时性的一个解决方案三种方式:最直接的就是在业务代码中去实现双写,也就是说每一次修改MySQL数据的时候,同时更新到ES中,注意:这种方法耦合度很高,一旦发生需求变更会有额外的一个维护......
  • 实战:MyBatis适配多种数据库:MySQL、Oracle、PostGresql等
    概叙很多时候,一套代码要适配多种数据库,主流的三种库:MySQL、Oracle、PostGresql,刚好mybatis支持这种扩展,如下图所示,在一个“namespace”,判断唯一的标志是id+databaseId,刚好写了三个同样的方法,一个不带databaseId,两个带databaseId,此时当前库如果连接的是oracle则执行databaseId=......
  • Django提示mysql版本过低:django.db.utils.NotSupportedError: MySQL 8 or later is re
    这个提示只是Django的版本检测提示,把它注释掉就好了。全局搜索函数:check_database_version_supported() 文件路径是:django_project\dj01\venv\Lib\site-packages\django\db\backends\base\base.py找到第二个,就是就是使用的那个,把它注释了: definit_connection_sta......
  • 在 MySQL Workbench 中升级 python
    MySQLWorkbench中的python版本不断受到安全标记,因为它不是最新版本。我的电脑上有最新版本,但在MySQL文件中它似乎是旧版本。我怎样才能更新,使其与我的电脑版本相同?尝试看看是否可以更新python,但没有运气很遗憾,你无法直接升级MySQLWorkbench内置的Python版本......
  • Django 测试设置错误:MySQL 后端的 django_content_type 表问题
    我在使用MySQL后端设置Django测试时遇到问题。该错误发生在测试数据库设置阶段,特别与django_content_type表相关。详细信息如下:环境:Django版本:5.0.7MySQL版本:8.0.37操作系统:Ubuntu20.04Python版本:3.11.12......
  • MySQL基础练习题9-平均售价
    题目·:查找每种产品的平均售价。average_price 应该 四舍五入到小数点后两位。准备数据​分析数据第一步:用左连接连接两张表​第二步:留下符合日期第三步:算平均售价第四步:排除那些售卖为0的这种情况总结:题目:查找每种产品的平均售价。average_price 应该 四舍五入到......
  • Mysql安装教程【实测有效】
     一、查找并卸载原有的mysql数据库1.使用rpm-qa|grepmysql命令查找mysql数据库软件包及依赖包;若没有任何显示则证明没有相关的mysql数据库;若显示了相关的软件包及依赖包,使用 yumremovexxx命令依次删除显示的包;注意:xxx为显示的软件包及依赖包包名;2.使用 find/......
  • Redis(三)事务、管道、主从复制
    事务事务是可以执行一个命令,也可以执行多个命令,事务本质上是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化地执行而不会被其他命令插入Redis事务和传统数据库的区别单独的隔离操作:Redis的事务仅仅是保证事务里面的操作会被连续独占的执行,redis命令的执行......