MySQL:事务的理解

一、CURD不加控制,会有什么问题 

(1)因为,MySQL里面存的是数据,所以很有可能会被多个客户访问,所以mysqld可能一次会接受到多个关于CURD的请求。(2)且mysql内部是采用多线程来完成数据存储等相关工作的,所以必然会存在对数据并发访问的场景      ——>会导致一些多请求并发可能产生的异常结果

       比如同行转账,按道理是我减100,你加100,但是因为我是同行所以用的是一张数据库的表,可能我减100的时候还没做完网络或者数据库出问题等其他原因导致没有给你加100,那么整个操作就会出现一个中间过程(我减了但是你没有加),这就有问题,在这种情况下我们允许异常产生,一旦操作没有完成我们应该把减掉的100再加回来,就好像什么都没做,等待下次合适的时候再去转账。这就相当于转账之后不要有中间过程,而是在转的时候一旦出现异常就直接进行回滚,因为不回滚的话就会有问题,必须得回滚保证和初始的状态一样,这就叫我们的回滚操作。在高并发的场景下数据或多或少都会出现这样的问题,所以这也就要求mysql必须要有针对这类问题的解决方案。

二、CURD满足什么属性,能解决上述问题?

1. 买票的过程得是原子的吧(要么不抢,要么抢到,出现中间状态会回滚)

2. 买票互相应该不能影响吧(我买的时候你正好过来,我的行为不能影响你,也就是彼此之间得是割裂的)

3. 买完票应该要永久有效吧 ( 购买成功这个情况必须得做持久化 )

4. 买前,和买后都要是确定的状态吧(买前就是没买,买后就是买了,不允许有不确定的状态)

三、什么是事务?

       事务就是一组DML语句组成,这些语句在逻辑上存在相关性(单独一条是没有意义的,比如转账就应该至少有两条sql语句,即我减100,你加100,整体在一起才有转账逻辑,所以事务一定要站在mysql的上层去看待sql语句,具体完成一个由多条sql语句构成的应用层功能,在业务上有具体含义的动作),这一组DML语句要么全部成功,要么全部失败,是一个整体。MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。

    事务就是要做的或所做的事情,主要用于处理操作量大,复杂度高的数据。假设一种场景:你毕业了,学校的教务系统后台 MySQL 中,不再需要你的数据,要删除你的所有信息(一般不会:) ), 那么要删除你的基本信息(姓名,电话,籍 贯等)的同时,也删除和你有关的其他信息,比如:你的各科成绩,你在校表现,甚至你在论坛发过的文章等。这样,就需要多条 MySQL 语句构成,那么所有这些操作合起来,就构成了一个事务。

      正如我们上面所说,一个 MySQL 数据库,可不止你一个事务在运行,同一时刻,甚至有大量的请求被包装成事务, 在向 MySQL 服务器发起事务处理请求。而每条事务至少一条 SQL ,最多很多 SQL ,这样如果大家都访问同样的表数据,在不加保护的情况,就绝对会出现问题。甚至,因为事务由多条 SQL 构成,那么,也会存在执行到一半出错或者 不想再执行的情况,那么已经执行的怎么办呢 ? 

      所以,一个完整的事务,绝对不是简单的sql集合,还需要满足如下四个属性:

1、原子性一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过 一样。

2、一致性在事务开始之前和事务结束以后,数据库的完整性没有被破坏。(一种状态变为另一种状态结果是可预期的)这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

3、隔离性数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交( Read uncommitted )、读提交 ( read committed )、可重复读( repeatable read )和串行化( Serializable )

4、持久性事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

mysql从技术上只要保证了134,就可以做到2,所以134是因 2是果(还需要上层用户配合) 

上面四个属性,可以简称为 ACID 。

原子性(Atomicity,或称不可分割性)

一致性(Consistency)

隔离性(Isolation,又称独立性)

持久性(Durability)

        mysql需要帮不同的客户端处理不同的事务请求,所以运行期间在自身内部必然存在大量的事务,所以他必须得将事务按照先描述后组织的形式管理起来,所以mysql会把这些事务打包描述成对象,然后放入到事务执行列表里,并帮我们解决一系列执行事务时可能出现的问题

四、为什么会有事务

       事务被 MySQL 编写者设计出来(不是天然就有的,而是使用过程中发现应用层需要才被设计出来的),本质是为了当应用程序访问数据库的时候,事务能够简化我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题.(你只需要说你的需求,其他的我帮你处理)可以想一下当我们使用事务时,要么提交,要么回滚,我们不会去考虑网络异常了,服务器宕机了,同时更改一个数据怎么办对吧?因此事务本质上是为了应用层服务的.而不是伴随着数据库系统天生就有的.

备注:我们后面把 MySQL 中的一行信息,称为一行记录

五、事务的版本支持

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持。

查看数据库引擎 :

mysql> show engines \G         -- 行显示
*************************** 1. row ***************************Engine: InnoDB    -- 引擎名称Support: DEFAULT   -- 默认引擎Comment: Supports transactions, row-level locking, and foreign keys--支持事务、行级锁,外键
Transactions: YES       -- 支持事务XA: YESSavepoints: YES       -- 支持事务保存点
*************************** 2. row ***************************Engine: MRG_MYISAMSupport: YESComment: Collection of identical MyISAM tables
Transactions: NOXA: NOSavepoints: NO
*************************** 3. row ***************************Engine: MEMORY    --内存引擎Support: YESComment: Hash based, stored in memory, useful for temporary tables
Transactions: NOXA: NO
Savepoints: NO
*************************** 4. row ***************************Engine: BLACKHOLESupport: YESComment: /dev/null storage engine (anything you write to it disappears)
Transactions: NOXA: NOSavepoints: NO
*************************** 5. row ***************************Engine: MyISAM    Support: YESComment: MyISAM storage engine
Transactions: NO           -- MyISAM不支持事务XA: NOSavepoints: NO
*************************** 6. row ***************************Engine: CSVSupport: YESComment: CSV storage engine
Transactions: NOXA: NOSavepoints: NO
*************************** 7. row ***************************Engine: ARCHIVESupport: YESComment: Archive storage engine
Transactions: NOXA: NOSavepoints: NO
*************************** 8. row ***************************Engine: PERFORMANCE_SCHEMASupport: YESComment: Performance Schema
Transactions: NOXA: NOSavepoints: NO
*************************** 9. row ***************************Engine: FEDERATEDSupport: NOComment: Federated MySQL storage engine
Transactions: NULLXA: NULLSavepoints: NULL
9 rows in set (0.00 sec)

六、事务的提交方式

事务的提交方式常见的有两种: 自动提交、手动提交

查看事务提交方式 :

show variables like 'autocommit';

 

用 SET 来改变 MySQL 的自动提交模式:

SET AUTOCOMMIT=0;            #SET AUTOCOMMIT=0 禁止自动提交

mysql> SET AUTOCOMMIT=1;           #SET AUTOCOMMIT=1 开启自动提交

七、事务常见操作方式

简单银行用户表

## Centos 7 云服务器,默认开启3306 mysqld服务
netstat -nltp

## 为了便于演示,我们将mysql的默认隔离级别设置成读未提交

set global transaction isolation level READ UNCOMMITTED;

## 设置了却没有用 ,因为需要重启终端才可以

select @@tx_isolation;

创建测试表

create table if not exists account(id int primary key, name varchar(50) not null default '', blance decimal(10,2) not null default 0.0
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

7.1 正常演示 - 证明事务的开始与(定向)回滚

mysql> show variables like 'autocommit';  -- 查看事务是否自动提交。我们故意设置成自动提交,看看该选项是否影响begin   从这一行往后所有的语句都属于这个事务+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit   | ON   |
+---------------+-------+
1 row in set (0.00 sec)
mysql> start transaction;               -- 开始一个事务begin也可以,推荐beginQuery OK, 0 rows affected (0.00 sec)
mysql> savepoint save1;                -- 创建一个保存点save1(根据需求设置保存点)Query OK, 0 rows affected (0.00 sec)
mysql> insert into account values (1, '张三', 100);   -- 插入一条记录Query OK, 1 row affected (0.05 sec)
mysql> savepoint save2;                 -- 创建一个保存点save2Query OK, 0 rows affected (0.01 sec)
mysql> insert into account values (2, '李四', 10000);  -- 在插入一条记录Query OK, 1 row affected (0.00 sec)
mysql> select * from account;             -- 两条记录都在了+----+--------+----------+
| id | name   | blance   |
+----+--------+----------+
|  1 | 张三   |   100.00 |
|  2 | 李四   | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
mysql> rollback to save2;                 -- 回滚到保存点save2(定向回滚)Query OK, 0 rows affected (0.03 sec)
mysql> select * from account;             -- 一条记录没有了+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)
mysql> rollback; -- 直接rollback,回滚在最开始,哪怕你一个回滚点都没设置也可以Query OK, 0 rows affected (0.00 sec)
mysql> select * from account;             -- 所有刚刚的记录没有了Empty set (0.00 sec)commit;--就是把该事务给提交了 无法回滚

但是一般我们很少手动rollback,事务大多数都是为了非正常情况 

7.2 非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)

-- 终端A
mysql> select * from account;          -- 当前表内无数据
Empty set (0.00 sec)mysql> show variables like 'autocommit'; -- 依旧自动提交
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit   | ON   |
+---------------+-------+
1 row in set (0.00 sec)mysql> begin;                            --开启事务
Query OK, 0 rows affected (0.00 sec)mysql> insert into account values (1, '张三', 100);   -- 插入记录
Query OK, 1 row affected (0.00 sec)mysql> select * from account;           --数据已经存在,但没有commit,此时同时查看终端B
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)
mysql> Aborted                          -- ctrl + \ 异常终止MySQL --终端B
mysql> select * from account;           --终端A崩溃前
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)mysql> select * from account;          --数据自动回滚
Empty set (0.00 sec)

 7.3 非正常演示2 - 证明commit了,客户端崩溃,MySQL数据不会在受影响,已经持久化

--终端 A 
mysql> show variables like 'autocommit'; -- 依旧自动提交 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) mysql> select * from account; -- 当前表内无数据 
Empty set (0.00 sec) mysql> begin; -- 开启事务 
Query OK, 0 rows affected (0.00 sec) mysql> insert into account values (1, '张三', 100); -- 插入记录 
Query OK, 1 row affected (0.00 sec) mysql> commit; --提交事务 
Query OK, 0 rows affected (0.04 sec) mysql> Aborted -- ctrl + \ 异常终止MySQL --终端 B 
mysql> select * from account; --数据存在了,所以commit的作用是将数据持久化到MySQL中 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) 

7.4 非正常演示3 - 对比试验。证明begin操作会自动更改提交方式,不会受MySQL是否自动提交影响

手动begin就必须手动commit,跟是否是自动提交毫无关系 

-- 终端 A 
mysql> select *from account; --查看历史数据 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) mysql> show variables like 'autocommit'; --查看事务提交方式 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) mysql> set autocommit=0; --关闭自动提交 
Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'autocommit'; --查看关闭之后结果 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | OFF | 
+---------------+-------+ 
1 row in set (0.00 sec) mysql> begin; --开启事务 
Query OK, 0 rows affected (0.00 sec) mysql> insert into account values (2, '李四', 10000); --插入记录 
Query OK, 1 row affected (0.00 sec) mysql> select *from account; --查看插入记录,同时查看终端B
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) mysql> Aborted --再次异常终止 -- 终端B 
mysql> select * from account; --终端A崩溃前 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) mysql> select * from account; --终端A崩溃后,自动回滚 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec)

7.5 非正常演示4 - 证明单条 SQL 与事务的关系

--实验一 
-- 终端A 
mysql> select * from account; 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) mysql> show variables like 'autocommit'; 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) mysql> set autocommit=0; --关闭自动提交 
Query OK, 0 rows affected (0.00 sec) mysql> insert into account values (2, '李四', 10000); --插入记录
Query OK, 1 row affected (0.00 sec) mysql> select *from account; --查看结果,已经插入。此时可以在查看终端B 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) mysql> ^DBye --ctrl + \ or ctrl + d,终止终端 --终端B 
mysql> select * from account; --终端A崩溃前 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) mysql> select * from account; --终端A崩溃后 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) -- 实验二 
--终端A 
mysql> show variables like 'autocommit'; --开启默认提交 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) mysql> select * from account; 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) mysql> insert into account values (2, '李四', 10000); 
Query OK, 1 row affected (0.01 sec) 
mysql> select *from account; --数据已经插入 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) mysql> Aborted --异常终止 --终端B 
mysql> select * from account; --终端A崩溃前 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) mysql> select * from account; --终端A崩溃后,并不影响,已经持久化。autocommit起作用 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 

7.6 结论

1、只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是否设置set autocommit无关。

2、事务可以手动回滚,同时,当操作异常,MySQL会自动回滚

3、对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select有特殊情况,因为 MySQL 有MVCC )

从上面的例子,我们能看到事务本身的原子性(回滚),持久性(commit)

7.7 事务操作注意事项  

1、如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务还没有提交)

2、如果一个事务被提交了(commit),则不可以回退(rollback)

3、可以选择回退到哪个保存点

savepoint save1; 设置保存点     rollback to save2;回退保存点

4、InnoDB 支持事务, MyISAM 不支持事务

5、开始事务可以使 start transaction 或者 begin

 0

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯刷题--宝石组合

在一个神秘的森林里,住着一个小精灵名叫小蓝。有一天,他偶然发现了一个隐藏在树洞里的宝藏,里面装满了闪烁着美丽光芒的宝石。这些宝石都有着不同的颜色和形状,但最引人注目的是它们各自独特的 “闪亮度” 属性。每颗宝石都有一个…

DAY06:【pytorch】图像增强

1、基本概念 数据增强,又称数据增广、数据扩增,是对训练集进行变换,使训练集更丰富,从而让模型更具泛化能力 2、裁剪 — — Crop 2.1 transforms.CenterCrop 功能:从图像中心裁剪图片 size:所需裁剪图…

mysql 禁止 读 某个 表

mysql 禁止 读 某个 表 mysql禁用某张表,禁用MySQL表的操作 https://shuyeidc.com/wp/89479.html MySQL严格禁止读取表如何避免数据泄露 https://www.kdun.cn/ask/394700.html select host,user from mysql.user; FLUSH PRIVILEGES; 1. MySQL严格禁止读取表如何避免数据泄露…

机器学习 从入门到精通 day_03

1. KNN算法-分类 1.1 样本距离判断 明可夫斯基距离:欧式距离,明可夫斯基距离的特殊情况;曼哈顿距离,明可夫斯基距离的特殊情况。 两个样本的距离公式可以通过如下公式进行计算,又称为欧式距离。 (…

LeetCode 热题 100_零钱兑换(85_322_中等_C++)(动态规划)

LeetCode 热题 100_零钱兑换(85_322) 题目描述:输入输出样例:题解:解题思路:思路一(动态规划): 代码实现代码实现(思路一(动态规划)&a…

游戏盾IP可以被破解吗

游戏盾IP(如上海云盾SDK、腾讯云游戏盾)是专为游戏行业设计的高防服务,旨在抵御DDoS攻击、CC攻击等威胁。其安全性取决于​​技术架构、防护能力​​以及​​运维策略​​。虽然理论上没有绝对“无法破解”的系统,但游戏盾IP在合理…

SpringBoot实战1

SpringBoot实战1 一、开发环境,环境搭建-----创建项目 通过传统的Maven工程进行创建SpringBoot项目 (1)导入SpringBoot项目开发所需要的依赖 一个父依赖:(工件ID为:spring-boot-starter-parent&#xf…

【软考-高级】【信息系统项目管理师】【论文基础】进度管理过程输入输出及工具技术的使用方法

定义 项目进度管理是为了保证项目按时完成,对项目中所需的各个过程进行管理的过程,包括规划进度、定义活动、活动优先级排序、活动持续时间、制定进度计划和控制进度。 管理基础 制定进度计划的一般步骤 选择进度计划方法(如关键路径法&a…

【Linux】之【Get】 chroot 环境下安装deb包时 .postinst:行 9: 201 段错误 (核心已转储)ldconfig

背景 如题,在postinst文件中直接执行了ldconfig命令, chroot 环境下出错,安装失败 分析 chroot 环境下不能用 ldconfig 和 systemctl 但是:如果环境是 chroot,系统有可能没完整挂载 /proc、/dev、系统路径&#xff…

【论文精读与实现】EDC²-RAG:基于动态聚类的文档压缩方法提升检索增强生成RAG性能

🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创AI未来! 🚀 1. 论文核心思想 这篇由清华大学团队提出的EDC-RAG框架,针对当前…

OSPF接口的网络类型和不规则区域

网络类型(数据链路层所使用的协议所构建的二层网络类型) 1、MA --- 多点接入网络 BMA --- 支持广播的多点接入网络 NBMA --- 不支持广播的多点接入网络 2、P2P --- 点到点网络 以太网 --- 以太网最主要的特点是需要基于MAC地址进行物理寻址,主要是因为以太网接口所连…

HTTP代理:内容分发战场上的「隐形指挥官」

目录 一、技术本质:流量博弈中的「规则改写者」 二、战略价值:内容分发的「四维升级」 三、实战案例:代理技术的「降维打击」 四、未来进化:代理技术的「认知升级」 五、结语:代理技术的「战略觉醒」 在数字内容爆…

(2)网络学习之堡垒机

堡垒机和防火墙的区别: 1.功能定位 防火墙主要负责抵御外部攻击,就像一道坚固的城墙,防止黑客进入内部网络。堡垒机则专注于内部管理,监控和记录运维人员的操作行为,确保内部网络的安全。 2.部署位置与作用范围 防…

minio命令行客户端mc常见用法

安装minio命令行客户端mc https://min-io.cn/docs/minio/linux/reference/minio-mc-admin.html # Windows安装minio命令行客户端 choco install minio-client -y# Linux安装mc客户端 wget -c -P /usr/local/bin/ https://dl.min.io/client/mc/release/linux-amd64/mc # 赋予可…

idea调整控制台日志显示长度

概述 在调试时,idea控制台显示的日志有长度显示,当显示的日志太长时,后生成的日志会覆盖掉之前生成的日志内容。想要调整长度就可以按以下方式进行设置。 设置方法 Settings -> Editor -> General -> Console -> Override con…

oracle em修复之路

很早以前写的文章,再草稿中存放太久了,今天开始整理20年来工作体会,以后陆续发出,希望给大家提供小小的帮助。 去年做的项目使用的oracle数据库,最近要看一下,启动机器进入系统,出现无法加载数…

QT中怎么隐藏或显示最大化、最小化、关闭按钮

文章目录 方法一:通过代码动态设置1、隐藏最大化按钮2、隐藏最小化按钮3、隐藏关闭按钮方法 1:移除 WindowCloseButtonHint方法 2:使用 Qt::CustomizeWindowHint 并手动控制按钮 4、同时隐藏最大化和最小化按钮5、同时隐藏最大化和关闭按钮6、…

性能比拼: Redis vs Memcached

本内容是对知名性能评测博主 Anton Putra Redis vs Memcached Performance Benchmark 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本视频中,我们将对比 Redis 和 Memcached。我会介绍一些功能上的不同,但主要关注 性能。 首先&#xf…

P1331 洛谷 海战

题目描述 思路 这个题需要读懂题意,即“什么样的形式表示两只船相撞?” ----> 上下相邻或左右相邻 如果图是不和法的,一定存在如下结构: # # . # 或 # # # . 或 # . # # 或 . # # #即四个格子里有三个#,一个"…

传统项目纯前端实现导出excel之xlsx.bundle.js

传统项目纯前端实现导出excel之xlsx.js 自从vue问世后,使得前端开发更加简洁从容,极大的丰富组件样式和页面渲染效果,使得前端功能的可扩展性得到极大地加强。虽然vue的使用对于前后端分离的项目对于功能实现与扩展有了质的飞跃,但…