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

2、mysql中的事务

时间:2024-01-26 18:12:35浏览次数:28  
标签:事务 版本号 存储 引擎 InnoDB mysql 日志

1. 事务日志

  • 事务日志可以帮助提高事务的效率。
    • 使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。
    • 事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序 IO,而不像随机 I0 需要在磁盘的多个地方移动磁头,所以采用事务日志的方式相对来说要快得多。
    • 事务日志持久以后,内存中被修改的数据在后台可以慢慢地刷回到磁盘。目前大多数存储引擎都是这样实现的,我们通常称之为预写式日志(Write-Ahead Logging),修改数据需要写两次磁盘。如果数据的修改已经记录到事务日志并持入化,但数据本身还没有写回磁盘,此时系统崩溃,存储引擎在重启时能够自动恢复这部分修改的数据。具体的恢复方式则视存储引擎而定。

2. MySQL 中的事务

  • MySQL提供了两种事务型的存储引擎: InnoDB和NDBCluster。另外还有一些第三方存储引擎也支持事务,比较知名的包括XtraDB和PBXT。

  • 自动提交(AUTOCOMMIT):MySQL默认采用自动提交(AUTOCOMMIT)模式。也就是说,如果不是显式地开始一个事务,则每个查询都被当作一个事务执行提交操作。在当前连接中,可以通过设置AUTOCOMMIT 变量来启用或者禁用自动提交模式:

image

  • 1或者0N表示启用,0或者0FF表示禁用。当AUTOCOMMIT=0时,所有的查询都是在一个事务中,直到显式地执行COMMIT提交或者ROLLBACK回滚,该事务结束,同时又开始了另一个新事务。
  • 修改 AUTOCOMMIT对非事务型的表,比如MyISAM或者内存表,不会有任何影响。对这类表来说,没有COMMIT或者ROLLBACK的概念,也可以说是相当于一直处于 AUTOCOMMIT 启用的模式
  • 另外还有一些命令,在执行之前会强制执行COMMIT提交当前的活动事务。典型的例子在数据定义语言(DDL)中,如果是会导致大量数据改变的操作,比如ALTER TABLE就是如此。另外还有LOCK TABLES等其他语句也会导致同样的结果。如果有需要,请检查对应版本的官方文档来确认所有可能导致自动提交的语句列表
  • MYSOL可以通过执行·SET TRANSACTION ISOLATION LEVEL命令来设置隔离级别。新的隔离级别会在下一个事务开始的时候生效。可以在配置文件中设置整个数据库的隔离级别,也可以只改变当前会话的隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

image

MySQL能够识别所有的4个ANSI隔离级别,InnoDB引擎也支持所有的隔离级别。

3. 在事务中混合使用存储引擎

  • MySOL服务器层不管理事务,事务是由下层的存储引擎实现的。所以在同一个事务中,使用多种存储引擎是不可靠的。
  • 如果在事务中混合使用了事务型非事务型的表(例如InnoDB和MyISAM表),在正常提交的情况下不会有什么问题。但如果该事务需要回滚非事务型的表上的变更就无法撤销,这会导致数据库处于不一致的状态,这种情况很难修复,事务的最终结果将无法确定。所以,为每张表选择合适的存储引擎非常重要。
  • 非事务型的表上执行事务相关操作的时候,MySOL通常不会发出提醒,也不会报错有时候只有回滚的时候才会发出一个警告:某些非事务型的表上的变更不能被回滚。但大多数情况下,对非事务型表的操作都不会有提示。

4.隐式和显式锁定

  • InnoDB 采用的是两阶段锁定协议(two-phase locking protocol)。在事务执行过程中,随时都可以执行锁定,只有在执行COMMIT或者ROLLBACK的时候才会释放,并且所有的锁是在同一时刻被释放。前面描述的锁定都是隐式锁定,InnoDB会根据隔离级别在需要的时候自动加锁。

  • InnoDB也支持通过特定的语句进行显式锁定,这些语句不属于SQL规范

    SELECT...LOCK IN SHARE MODE
    SELECT ... FOR UPDATE
    
  • MySQL也支持LOCK TABLESUNLOCK TABLES语句,这是在服务器层实现的,和存储引擎无关。它们有自己的用途,但并不能替代事务处理。如果应用需要用到事务,还是应该选择事务型存储引擎

  • 应用已经将表从MyISAM转换到InnoDB,但还是显式地使用LOCK TABLES语句。这不但没有必要,还会严重影响性能,实际上InnoDB行级锁工作得更好。

  • LOCK TABLES和事务之间相互影响的话,情况会变得非常复杂,在某些MySQL版本中甚至会产生无法预料的结果。因此,除了事务中禁用了AUTOCOMMIT可以使用 LOCK TABLES之外,其他任何时候都不要显式地执行LOCK TABLES,不管使用的是什么存储引擎。

5. 多版本控制

  • MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。

  • MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

  • 不同存储引擎的MVCC实现是不同的,典型的有乐观(optimistic)并发控制和悲观(pessimistic)并发控制。

  • InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号(system version number)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

    看一下在REPEATABLE READ隔离级别下,MVCC具体是如何操作的。

    • SELECT
      InnoDB会根据以下两个条件检查每行记录:

    • InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的

    • 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

    只有符合上述两个条件的记录,才能返回作为查询结果

    • INSERT
      InnoDB为新插入的每一行保存当前系统版本号作为行版本号

    • DELETE
      InnoDB为删除的每一行保存当前系统版本号作为行删除标识,

    • UPDATE
      InnoDB为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

    保存这两个额外系统版本号,使大多数读操作都可以不用加锁。这样设计使得读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

标签:事务,版本号,存储,引擎,InnoDB,mysql,日志
From: https://www.cnblogs.com/ccblblog/p/17990390

相关文章

  • The artifact mysql:mysql-connector-java:jar:8.0.33 has been relocated to com.mys
    Theartifactmysql:mysql-connector-java:jar:8.0.33hasbeenrelocatedtocom.mysql:mysql-connector-j:jar:8.0.33:MySQLConnector/Jartifactsmovedtoreverse-DNScompliantMaven2+coordinates.1.异常信息Theartifactmysql:mysql-connector-java:jar:8.0.33hasb......
  • 1、mysql概述
    1.连接管理与安全性每个客户端连接都会在服务器进程中拥有一个线程,这个连接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。服务器会负责缓存线程,因此不需要为每一个新建的连接创建或者销毁线程。当客户端(应用)连接到MySOL服务器时,服务器需要......
  • 数据库安全||MySQL数据库安全中MySQL权限表:包括用户管理、权限管理等&用户管理:创建、
    MySQL数据库安全:MySQL数据库安全:MySQL权限表:包括用户管理、权限管理等。用户管理:创建、修改、删除用户账号。权限管理:查看、授予和撤销用户权限。1.MySQL数据库中的权限表是存储用户权限信息的核心部分,它们位于mysql数据库中。这些权限表包含了用户账号、密码、权限以及其他与用户......
  • MySQL5 安装
    Custom安装选择模块自定义位置不同以往,此次可以将MySQL安装到C盘以外,这样更加便于分类管理。关闭更新MySQL默认自动会凌晨检查更新,因此关闭。......
  • MySQL数据库优化的八种方式(经典必看)
    MySQL数据库优化的八种方式(经典必看)引言:关于数据库优化,网上有不少资料和方法,但是不少质量参差不齐,有些总结的不够到位,内容冗杂偶尔发现了这篇文章,总结得很经典,文章流量也很大,所以拿到自己的总结文集中,积累优质文章,提升个人能力,希望对大家今后开发中也有帮助1、......
  • MySQL间隙锁死锁问题
    一、场景还原当时同事A在线上代码中使用了Mybatis-plus的如下方法com.baomidou.mybatisplus.extension.service.IServicesaveOrUpdate(T, com.baomidou.mybatisplus.core.conditions.Wrapper<T>)该方法先执行了update操作,如果更新到就不再执行后续操作,如果没有更新到,才进行主......
  • 事务的隔离级别及脏读,不可重复读,幻读等问题
    事务隔离级别以及对应的问题如上所示。读未提交:在修改数据时在没有提交时就修改了数据库,如果修改回滚则又修改为原值,这样的话在修改与回滚之间读取的数据就是不准确的,会产生脏读现象。脏读现象是读取到未修改的数据,即是数据逻辑上不存在的数据(因为回滚未提交),而下面产生的问题均......
  • 了解Java事务管理
    在软件开发过程中,事务管理是一个非常重要的概念.事务用于确保数据库操作的一致性和完整性,并且具有原子性、一致性、隔离性和持久性的特性.Java提供了强大的事务管理机制,使得我们能够更好地处理数据的一致性和并发控制.Java事务管理主要通过JavaTransactionAPI(JTA)和Java......
  • MySQL SQL点查,范围查,排序,分组的Explain分析和SQL优化(8.0版本)
    MySQLSQL常用优化主要有where,range,order,groupby,or等查询。下图是优化的原则,后面会有一个例子来看看:比如建立了联合索引(c1,c2,c3),索引长度分别为5,5,4。数据有50条:点查SELECT*FROMtraining.t1wherec3=1andc2=1andc1=1;使用了索引,只要全部包含索引列,那么点查顺序......
  • Spring的事务使用教程
    什么是事务?事务(Transaction)是数据库操作最基本单元,逻辑上一组操作,要么都成功,要么都失败,如果操作之间有一个失败所有操作都失败。事务四个特性(ACID)原子性一组操作要么都成功,要么都失败。一致性一组数据从事务1合法状态转为事务2的另一种合法状态,就是一致。隔离性事务1......