MySQL进阶之(十)事务和隔离级别

十、事务和隔离级别

  • 10.1 事务
    • 10.1.1 事务介绍
    • 10.1.2 事务四大特性
    • 10.1.3 事务的状态
    • 10.1.4 如何使用事务
      • 01、事务控制语句
      • 02、事务操作
  • 10.2 事务的隔离级别
    • 10.2.1 事务数据可见性和并发问题
      • 01、脏写(Dirty Write)/更新丢失
      • 02、脏读(Dirty Read)/读未提交
      • 03、不可重复读(Non-Repeatable Read)/读已提交
      • 04、幻读(Phantom)/可重复读
    • 10.2.2 四种隔离级别
    • 10.2.3 设置事务的隔离级别
    • 10.2.4 隔离级别的选择

10.1 事务

10.1.1 事务介绍

MySQL 事务主要用于处理操作量大、复杂度高的数据。比如:张三给李四转钱这个操作,必须同时完成两步:扣除张三账户中的钱、新增李四账户中的钱。这两步数据库操作就构成了一个事务。

事务是一组逻辑操作单元,使数据从一种状态变换到另一种状态。事务是数据库区别于文件系统的重要特性之一,有了事务就会让数据库始终保持一致性,同时还能通过事务机制恢复到某个时间点,这样可以保证已提交到数据库的修改不会因为系统崩溃而丢失。

  • 在 MySQL 中只有使用了 InnoDB 存储引擎的数据库或表才支持事务。
  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
  • 事务用来管理 insert、update、delete语句。

事务处理的原则:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交,那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚到最初状态。

10.1.2 事务四大特性

一般来说,事务必须满足 4 个条件(ACID):原子性(Atomicity,或称为不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

  • 原子性指事务是一个不可分割的工作单位,要么全部提交,要么全部失败回滚,不存在中间的状态。如果事务执行过程中发生错误,那么就会被回滚到事务开始前的状态,就像这个事务从来没有被执行过一样。
  • 一致性指事务执行前后,数据从一个合法性状态变换到另一个合法性状态,数据库的完整性没有被破坏。其中,满足预定的约束的状态就叫做合法的状态,这个状态是由自己定义的。
  • 隔离性指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的。隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同的隔离级别,包括读未提交(Read uncommitted)、读提交(Read committed)、可重复读(Repeatable read)和串行化(Serializable)。
  • 持久性指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,即便是系统故障也不会丢失。持久性是通过事务日志来保证的,包括重做日志和回滚日志。

总结:ACID 是事务的四大特性,在这四个特性中,原子性是基础,隔离性是手段,一致性是约束条件,而持久性是目的。

注意:在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT = 0,用来禁止使用当前会话的自动提交。

10.1.3 事务的状态

事务其实是一个抽象的概念,它其实对应着一个或多个数据库操作,MySQL 根据这些操作所执行的不同阶段把事务大致分成几个状态:

  • 活动的(active):事务对应的数据库操作正在执行过程中时,就说该事务处在活动的状态。
  • 部分提交的(partially committed):当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响并没有刷新到磁盘时,就说该事务处在部分提交的状态。
  • 失败的(failed):事务处在活动的或部分提交的状态时,可能遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行,或者人为的停止当前事务的执行,就说该事务处在失败的状态。
  • 中止的(aborted):如果事务执行了一部分而变为失败的状态,那么就需要把已经修改的事务中的操作还原到事务执行前的状态。也就是要撤销失败事务对当前数据库造成的影响,这个撤销的过程也称为回滚。当回滚操作执行完毕时,也就是数据库恢复到了执行事务之前的状态,就说该事务处在了中止的状态。
  • 提交的(committed):当一个处在部分提交状态的事务将修改过的数据都同步到磁盘上后,就说该事务处在了提交的状态。

在这里插入图片描述

10.1.4 如何使用事务

01、事务控制语句

  • BEGIN 或 START TRANSACTION 显式地开启一个事务;
  • COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;
  • ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
  • SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;
  • RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
  • ROLLBACK TO identifier 把事务回滚到标记点;
  • SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

02、事务操作

MySQL 事务分为隐式事务显式事务,默认是隐式事务。执行 insert、update、delete 操作的时候,数据库自动开启事务、提交事务或回滚事务。其中,是否开启隐式事务是由变量 autocommit 控制的,该值默认情况下为 true。

⭐ 显式事务

事务需要手动开启、提交或回滚,由开发者自己控制。其中,一个事务的完成过程分为三个步骤:

  • 步骤1:开启事务

    使用 START TRANSACTION 或 BEGIN 显式开启一个事务:

    BEGIN;
    START TRANSACTION;
    

    其中, START TRANSACTION 语句与 BEGIN 相比,后面能跟几个修饰符。
    ① READ OLAY:标识当前事务是一个只读事务,也就是属于该事务的数据库操作只能读取数据,而不能修改数据。
    ② READ WAITE:标识当前事务是一个读写事务,属于该事务的数据库操作既可以读取数据,也可以修改数据。
    ③ WAIT CONSISTENT SNAPSHOT:启动一致性读。

    注意:READ OLAY 和 READ WAITE 是用来设置所谓的事务访问模式的,就是以只读还是读写的方式来访问数据库中的数据。一个事务的访问模式不能同时设置为只读的也设置为读写的。
    另外,只读事务中只是不允许修改那些其他事务也能访问到的表中的数据,对于临时表来说(使用 create tmeporary table 创建的表),由于它们只能在当前会话中可见,所以只读事务其实也是可以对临时表进行增、删、改操作的。

  • 步骤2:一系列 DML 操作(不含 DDL)

  • 步骤3:事务结束的状态(提交或中止)

    # 提交事务,当事务提交后,对数据库的修改是永久性的
    commit;
    # 回滚事务。即撤销正在进行的所有没有提交的修改
    rollback;
    # 将事务回滚到某个保存点
    rollback to [savepoint]
    

    其中,关于 savepoint 相关的操作有:

    # 在事务中创建保存点,方便后续针对保存点进行回滚。一个事务中可以存在多个保存点
    savepoint 保存点名称;
    # 删除某个保存点
    release savepoint 保存点名称;
    

    如果中间操作错误,就使用 savepoint 来设定一个保存点,将事务回滚到某个保存点。

⭐ 隐式事务

MySQL 中有一个系统变量 autocommit:

SHOW VARIABLES LIKE '%autocommit%';

在这里插入图片描述
默认情况下,如果不显式的使用 START TRANSACTION 或 BEGIN 语句开启一个事务,那么每一条语句都算是一个独立的事务,这种特性称为事务的自动提交。也就是说,不以 START TRANSACTION 或 BEGIN 语句显式的开启一个事务,每条语句都相当于是在一个独立的事务中执行。

如果想要关闭这种自动提交的功能,可以使用下面两种方法:

  • 显式的使用 START TRANSACTION 或 BEGIN 语句开启一个事务。这样在本次事务提交或回滚前会暂时关闭掉自动提交的功能。
  • 将系统变量 autocommit 的值设置为 OFF
    set autocommit = OFF;
    # 或
    set autocommit = 0;
    
    这样写入的多条语句就算是属于同一个事务了,直到显式的写出 commit 语句来把这个事务提交掉,或者显式的写出 rollback 语句来把这个事务回滚掉。

总结:默认情况下 autocommit 为 true,在没有 START TRANSACTION 或 BEGIN 时,DML 语句会自动提交。当 autocommit 为 false 时,DML 不会自动提交。但是,DDL 语句不受 autocommit 变量的影响,都会自动提交。

10.2 事务的隔离级别

MySQL 是一个客户端/浏览器架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接,每个客户端与服务器连接上之后,就可以称为一个会话(Session)。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就是对于服务器来说可能同时处理多个事务。事务有隔离性的特性,理论上在某个事务对某个数据进行访问时,其他事务应该进行排队,当该事务提交之后,其他事务才可以继续访问这个数据。但是这样对性能的影响太大了,我们既想保持事务的隔离性,又想让服务器在处理访问同一数据的多个事务时性能尽量高些,那就要看二者如何权衡取舍了。

10.2.1 事务数据可见性和并发问题

下面是访问相同数据的事务在不保证串行执行的情况下可能会出现的问题:

01、脏写(Dirty Write)/更新丢失

对于两个事务 A、B,如果事务 A 修改了事务 B 未提交的已修改的数据,那就意味着发生了脏写。如下图所示,如果事务 B 回滚了,就会造成事务 A 已提交的数据丢失。
在这里插入图片描述

Session A 和 Session B 各开启了一个事务,Session B 中的事务先将 studentno 列为 1 的记录的 name 更新为 ‘李四’,然后 Session A 中的事务又接着把这条 studentno 列为 1 的记录的 name 更新为 ‘张三’。如果 Session B 中的事务在最后进行了回滚,那么 Session A 中的更新也将不存在,这个现象就称为脏写。

02、脏读(Dirty Read)/读未提交

对于两个事务 A、B,如果事务 A 读取了已经被事务 B 更新了但还没有被提交的数据,之后事务 B 回滚了,事务 A 读取的内容就是临时且无效的。
在这里插入图片描述

在 Session A 和 Session B 中各开启了一个事务,Session B 中的事务先将 studentno 列为 1 的记录的 name 列更新为 ‘张三’,然后 Session A 中的事务再去查询这条 studentno 为 1 的记录,如果读到列 name 的值为 ‘张三’,而Session B 中的事务进行了回滚,那么 Session A 中相当于读到了一个不存在的数据,这种现象就叫做脏读。

03、不可重复读(Non-Repeatable Read)/读已提交

对于两个事务 A、B,事务 A 读取了一个字段,然后事务 B 更新了该字段。之后事务 A 再次读取同一个字段时,与第一次读取到的值不一样了,这就意味着发生了不可重复读。
在这里插入图片描述
上图中 Session B 中提交了几个隐式事务,这些事务都修改了 studentno 列为 1 的记录的列 name 的值,每次事务提交后,如果 Session A 中的事务都可以看到最新值,这种现象就被称为不可重复读。

04、幻读(Phantom)/可重复读

对于两个事务 A、B,事务 A 从一个表中读取了一个字段,然后事务 B 在该表中插入了一些新的行。之后,如果事务 A 再次读取同一个表,就会多出几行数据,这就意味着发生了幻读。

在这里插入图片描述
Session A 中的事务先根据条件 studentno > 0 这个条件查询表 student,得到了 name 列值为 ‘张三’ 的记录。之后 Session B 中提交了一个隐式事务,向表 student 中插入了一条新记录。当 Session A 中的事务再次根据相同的条件 studentno > 0 查询表 student 时,得到的结果集中包含 Session B 中的事务新插入的那条记录 ,这种现象被称为幻读。

注意:

  1. 幻读强调的是一个事务按照某个相同条件多次读取记录时,后读取到了之前没有读到的记录。
  2. 对于之前已经读取到的记录,之后又读取不到了这种情况,相当于是每一条记录都发生了不可重复读的现象。

10.2.2 四种隔离级别

事务的隔离级别主要是解决了多个事务之间数据可见性及数据正确性的问题(或者说为了解决并发控制可能产生的异常问题),数据库定义了四种事务的隔离级别:

  • READ UNCOMMITTED:读未提交。在该隔离级别下,所有事务都可以看到其他未提交事务的执行结果。不能避免脏读、不可重复读、幻读。
  • READ COMMITTED:读已提交。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这是大多数数据库系统的默认隔离级别(但不是 MySQL 默认的)。可以避免脏读,但不可重复读、幻读问题仍然存在。
  • REPEATABLE READ :可重复读。事务 A 在读到一条数据之后,此时事务 B 对该数据进行了修改并提交,那么事务 A 再读该数据,读到的还是原来的内容。可以避免脏读、不可重复读,但幻读问题仍然存在。这是 MySQL 的默认隔离级别
  • SERIALIZABLE:可串行化。确保事务可以从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作。所有的并发问题都可以避免,但性能十分低下。能避免脏读、不可重复读和幻读。

在上面四种隔离级别中,隔离级别越高,数据库的并发性能就越差:
在这里插入图片描述
在 SQL 标准中规定,针对不同的隔离级别,并发事务可以发生不同严重程度的问题:

隔离级别脏读可能性不可重复读可能性幻读可能性
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE

无论哪种隔离级别,都不允许脏写的情况发生,因为脏写这个问题太严重了。

注意:
在 MySQ L中,REPEATABLE-READ 也是可以避免幻读的,通过加行锁(独占锁)(select * from … for update)实现。同时即便当前记录不存在,比如 id=3 不存在,当前记录也会获取一把记录锁(因为 InnoDB 的行锁锁定的是索引,与记录实体存不存在没关系,存在就加 X锁,不存在就加间隙锁 ),其他事务则无法插入索引的记录,故杜绝幻读。
在 SERIALIZABLE 隔离级别下,MySQL 会隐式的添加行(X)锁/gap(X)锁,从而其他事务会被阻塞。

10.2.3 设置事务的隔离级别

MySQL支持标准的四种隔离级别,默认隔离级别为 REPEATABLE-READ:

show variables like 'transaction_isolation';
# 或
select @@transaction_isolation;# MySQL 5.7.20 之前 
show variables like 'tx_isolation';

在这里插入图片描述
设置事务的隔离级别,可通过修改配置文件和 set 命令。

修改配置文件

修改mysql中的my.init文件,将隔离级别设置为:READ-COMMITTED,如下:

transaction-isolation=READ-COMMITTED

通过 set 命令

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level;
-- 其中level有4种值:
level: {REPEATABLE READ| READ COMMITTED| READ UNCOMMITTED| SERIALIZABLE
}-- 或者
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION LEVEL
-- 其中level有4种值:
level: {REPEATABLE-READ| READ-COMMITTED| READ-UNCOMMITTED| SERIALIZABLE
}

关于设置时使用 GLOBAL 或 SESSION 的影响:

  • 使用 GLOBAL 关键字(在全局范围影响)

    当前已经存在的会话无效。只针对执行完该语句之后产生的会话起作用。

  • 使用 SESSION 关键字(在会话范围影响)

    对当前会话的所有后续的事务有效。如果在事务之间执行,则对后续的事务有效。该语句可以在已经开启的事务中间执行,但不会影响当前正在执行的事务。

10.2.4 隔离级别的选择

  • 读未提交( Read Uncommitted )

    读未提交是隔离级别最低的一种事务级别。在这种隔离级别下,一个事务会读到另一个事务更新后但未提交的数据,如果另一个事务回滚,那么当前事务读到的数据就是脏数据,这就是脏读(Dirty Read)。

  • 读已提交( Read Committed )

    在 Read Committed 隔离级别下,一个事务可能会遇到不可重复读(Non Repeatable Read)的问题。不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。

  • 可重复读( Repeatable Read )

    在 Repeatable Read 隔离级别下,一个事务可能会遇到幻读(Phantom Read)的问题。幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。幻读就是没有读到的记录,以为不存在,但其实是可以更新成功的,并且,更新成功后,再次读取,就出现了。

  • 可串行化( Serializable )

    Serializable 是最严格的隔离级别。在 Serializable 隔离级别下,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。 虽然 Serializable 隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用Serializable隔离级别。

隔离级别越高,并发性也低,比如最高级别 SERIALIZABLE 会让事物串行执行,并发操作变成串行了,会导致系统性能直接降低。

读已提交(READ-COMMITTED)、可重复读( Repeatable Read )通常用的比较多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1486149.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Python怎样读取URL生成PDF

1. 安装依赖的exe 需要在这个网址,安装一个exe包,地址:https://wkhtmltopdf.org/ 进入网址后,点这个位置: 选择一个你的操作系统的下载链接: 安装后的exe文件: C:\Program Files\wkhtmltopdf…

分布式服务框架zookeeper+消息队列kafka

一、zookeeper概述 zookeeper是一个分布式服务框架,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:命名服务,状态同步,配置中心,集群管理等。 在分布式环境下,经常需要对应用/服…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十四章 注册字符设备号

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

硅谷裸机云大宽带服务器连接不上是怎么回事?该如何处理

硅谷裸机云大宽带服务器连接不上的常见原因主要有网络设置、网络设备、服务端、软件和服务、物理层等,出现以上问题,RAK部落小编建议大家可以通过以下一系列的方法进行排查和解决。具体分析如下: 1.检查网络设置   核对配置信息&#xff1a…

微信小程序-CANVAS写入图片素材、文字等数据生成图片

微信小程序中,CANVAS写入图片素材、文字等数据生成图片,最终可将生成的 base64 格式图片保存至相册操作 Tips: 1、canvas 标签默认宽度 300px、高度 150px canvas 生成图片时,写入图片素材、文字等数据前,需要根据实…

LangChain的使用详解

一、 概念介绍 1.1 Langchain 是什么? 官方定义是:LangChain是一个强大的框架,旨在帮助开发人员使用语言模型构建端到端的应用程序,它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供…

nfs和web服务器的搭建

(一)web服务器的搭建 1.配置基本环境 要点有,yum源,包含nginx和阿里云(或者腾讯云或者华为云),这里的相关知识可以参考之前的yum配置笔记 2.安装nginx yum -y install nginx 3.验证并且开启服…

VS Code 配置 C/C++ 编程运行环境(保姆级教程)

文章目录 一、软件下载1. 下载 VS Code 安装工具 2. 下载 MinGW-W64二、安装 VS Code三、安装 MinGW-W64 及配置环境变量四、配置 VS Code 的 C/C 编程运行环境1. 汉化 VS Code(选做)2. 安装 C/C 扩展包 五、测试 VS Code 的 C/C 编程环境1. 创建代码文件…

C++学习笔记01-语法基础(问题-解答自查版)

前言 以下问题以Q&A形式记录,基本上都是笔者在初学一轮后,掌握不牢或者频繁忘记的点 Q&A的形式有助于学习过程中时刻关注自己的输入与输出关系,也适合做查漏补缺和复盘。 本文对读者可以用作自查,答案在后面&#xff0…

求职学习day8

7/21回顾: 用面试鸭的意义可能就在于将知识点用问答的形式具象化在脑海,不然可能只停留在听说过的感觉 7.21 玩了一天。一个很不好的信号。今天下午要试试把 mall 项目的代码运行过一遍。 项目运行问题: 问题 1 :两个门服务器…

【HarmonyOS】HarmonyOS NEXT学习日记:六、渲染控制、样式结构重用

【HarmonyOS】HarmonyOS NEXT学习日记:六、渲染控制、样式&结构重用 渲染控制包含了条件渲染和循环渲染,所谓条件渲染,即更具状态不同,选择性的渲染不同的组件。 而循环渲染则是用于列表之内的、多个重复元素组成的结构中。 …

Redis集群部署Windows版本

Redis集群 之前因为数据量的原因,并没有进行Redis集群的配置需要,现在由于数据量大,需要进行集群部署。 最初在windows系统部署,需要Redis的windows版本,但官方没有windows版本,所以需要去gitHub上找由民…

R语言统计分给——数据管理2

参考资料:R语言实战【第2版】 1、日期值 日期值通常以字符串的形式输入R中,然后转化为数值形式存储的日期边阿玲。函数as.Date()用于执行这种转化。其语法为as.Date(x,"input_format"),其中x是字符型数据,input_format…

Ubuntu 24.04 LTS Noble安装 FileZilla Server

FileZilla Server 是一款使用图形用户界面快速创建 FTP 服务器的软件。它有助于测试需要 FTP 服务器功能的各种项目。虽然早期的 FileZilla FTP 服务器仅适用于 Windows 和 macOS,但现在我们也可以在 Linux(例如 Ubuntu 24.04)上安装 FileZil…

CatBoost模型Python代码——用CatBoost模型实现机器学习

一、CatBoost模型简介 1.1适用范围 CatBoost(Categorical Boosting)是一种基于梯度提升的机器学习算法,特别适用于处理具有类别特征的数据集。它可以用于分类、回归和排序任务,并且在处理具有大量类别特征的数据时表现优异。典型…

安装好anaconda,打开jupyter notebook,新建 报500错

解决办法: 打开anaconda prompt 输入 jupyter --version 重新进入jupyter notebook: 可以成功进入进行代码编辑

你了解你的GD32 MCU系统主频是多少吗 ?

系统时钟是GD32 MCU的时基,可以理解为系统的心跳,片上所有的外设以及CPU最原始的时钟都来自于系统时钟,因而明确当前系统时钟是多少非常重要,只有明确了系统时钟,才能够实现准确的定时、准确的采样间隔以及准确的通信速…

回溯题目的套路总结

前言 昨天写完了LeeCode的7,8道回溯算法的题目,写一下总结,这类题目的共同特点就是暴力搜索问题,排列组合或者递归,枚举出所有可能的答案,思路很简单,实现起来的套路也很通用,一…

win10安装ElasticSearch7.x和分词插件

说明: 以下内容整理自网络,格式调整优化,更易阅读,希望能对需要的人有所帮助。 一 安装 Java环境 ElasticSearch使用Java开发的,依赖Java环境,安装 ElasticSearch 7.x 之前,需要先安装jdk-8。…

unity 实现图片的放大与缩小(根据鼠标位置拉伸放缩)

1创建UnityHelper.cs using UnityEngine.Events; using UnityEngine.EventSystems;public class UnityHelper {/// <summary>/// 简化向EventTrigger组件添加事件的操作。/// </summary>/// <param name"_eventTrigger">要添加事件监听的UI元素上…