目錄
Redis
操作錯誤
語法錯誤
文件釋義
Errors inside a transaction
MySQL
操作错误
语法错误
Redis 为什么没有回滚?
总结
首頁 資料庫 mysql教程 MySQL和Redis事務的比較(圖文)

MySQL和Redis事務的比較(圖文)

Mar 30, 2019 am 10:53 AM
mysql redis

這篇文章帶給大家的內容是關於MySQL和Redis事務的比較(圖文),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

簡言:一般來說,事務是必須滿足4個條件(ACID)::原子性(Atomicity,或稱為不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱為獨立性)、持久性(Durability)。

從標題來看,既然都是事務,那之間有什麼差別?來一一解開,先從兩個資料庫說去。

MySQL 屬於 關聯式資料庫 , Redis 屬於 非關係型資料庫,兩者對交易有著不同的解釋。

(相關建議:MySQL教學Redis教學

Redis

[1] Redis 交易可以一次執行多個命令, 並且帶有以下兩個重要的保證:

  • 批次操作在發送EXEC 命令前被放入佇列快取。
  • 收到 EXEC 指令後進入事務執行,事務中任意指令執行失敗,其餘的指令仍被執行。
  • 在交易執行過程,其他客戶端提交的命令請求不會插入到交易執行命令序列中。

一個交易從開始到執行會經歷以下三個階段:

  • 開始交易。
  • 命令入隊。
  • 執行交易。

單一 Redis 指令的執行是原子性的,但 Redis 並沒有在事務上增加任何維持原子性的機制,所以 Redis 事務的執行並不是原子性的。

交易可以理解為一個打包的批次執行腳本,但批次指令並非原子化的操作,中間某指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做。

操作錯誤

看著有點兒繞口,那就實際執行一下 看一下結果。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set tr_1 233
QUEUED
127.0.0.1:6379> lpush tr_1 666
QUEUED
127.0.0.1:6379> set tr_2 888
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK
登入後複製

在上面的事務中,設定了一個key 為tr_1 的字串數據,然後又透過lpush 來添加元素,這很明顯是錯誤的操作方式,當我們提交事務候出現了一個操作錯誤,這時候我們來看看tr_1 的值是什麼。

127.0.0.1:6379> get tr_1
"233"
登入後複製

透過 get 指令來的tr_1 內容還是 233 ,並沒有變,那再看一下其他的。

127.0.0.1:6379> keys *
1) "tr_2"
2) "tr_1"
127.0.0.1:6379> get tr_2
"888"
127.0.0.1:6379>
登入後複製

這裡可以看到tr_2 存在,並列印了值,這時候我們發現,即使出現了操作錯誤 ,但是錯誤並沒有致使執行停止,錯誤之後的語句也執行了並成功執行,似乎符合上述的中間某指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做。

語法錯誤

NO~,這時候還有另一個情況語法錯誤

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set tr_1 233
QUEUED
127.0.0.1:6379> lpush tr_1 666
QUEUED
127.0.0.1:6379> set
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> set 233
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> set tr_2 888
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> keys *
(empty list or set)
登入後複製

當我們執行到 set時沒有給任何參數,第二次執行時故意少給了一個參數。可以看到報了 語法錯誤,最後提交事務,也告訴了我們事務因為錯誤被丟失了,接著用 keys *檢索發現確實如此。

文件釋義

這裡可以官方文件中提到的

Errors inside a transaction

// 在執行過程中可能會遇到兩種錯誤命令錯誤。

During a transaction it is possible to encounter two kind of command errors:

// 1.指令無法進入佇列,例如:參數數量錯誤,指令名錯誤...,或某些關鍵錯誤如記憶體不足

  • A command may fail to be queued, so there may be an error before EXEC is called. For instance the command may be syntactically wrong (wrong number of arguments, wrong command name, ...), or there may be some critical condition like an out of memory condition (if the server is configured to have a memory limit using the maxmemory##didirective)。
  • ##//
2

. 對鍵進行錯誤的操作如上面的對字串使用lpush

A command may fail
    after
  • EXEC is called, for instance since we performed an operation against a key with the wrong value (like calling a list operation against a string value).
  • #// 客戶端檢查鍵入的命令,大多數時候會在呼叫
exec

前發現第一類錯誤,如果指令執行回傳來QUEUED 則表示指令正常進入佇列,否則錯誤,大多數情況下客戶端會終止放棄這個事務。 <p>Clients used to sense the first kind of errors, happening before the EXEC call, by checking the return value of the queued command: if the command replies with QUEUED it was queued correctly, otherwise Redis returns an error. If there is an error while queueing a command, most clients will abort the transaction discarding it.</p>

关于 Redis 暂时看到这里 接下来看到 MySQL

MySQL

众所周知,MySQL 只有 InnoDB 引擎支持 事务,在启用 MySQL 事务之前需要先停掉自动提交

测试表结构 user

类型 注释
id int(11) 自动增量 主键ID
money int(11) [0] 金钱
title varchar(500) NULL 称呼

在这里来模拟一个转账的操作:AB100元

步骤解析 A+100 元,B -100元,即两步虽然很简单,简单走一下流程。

MySQL和Redis事務的比較(圖文)

可以看到,没有问题,那么我们从中人为的制造一些问题呢?

操作错误




类型 注释
id int(11) 自动增量
money int(11) unsigned [0]
title varchar(500) NULL

这里我们把 money 字段变成了无符号,即不能小于 0,并且,调整数据库中的数据如下。

`SELECT * FROM `user` LIMIT 50` (0.000 秒)
登入後複製
修改 id money title
编辑 1 10000 A
编辑 2 0 B

接着执行下面的 SQL

select version();
SET AUTOCOMMIT=0;
begin;
select * from user where title in ('A','B') for update;
update user set  money = money + 1000 where title = 'A';
update user set money = money - 1000 where title = 'B';
select * from user where title in ('A','B');
commit;
登入後複製

MySQL和Redis事務的比較(圖文)

问题出现了,这里报出了错误,但是可以看到 前面的 SQL 已经是已执行的了,结果已经发生了变化,从这里看,似乎和 Redis 的处理差不多,除了错误之后语句继续执行。但是 值的注意的是, 在我们实际开发中,这种情况程序会直接抛出异常,以供我们在 catch 块中执行 rollback ,以回滚操作确保数据完整,即使是单独使用 MySQL 命令行 我们也可以用存储过程来对异常进行回滚。

语法错误

刚刚看到 Redis 当遇到 语法错误 时会自动丢弃事务,阻止提交,那 MySQL 呢?

MySQL和Redis事務的比較(圖文)

答案:不会,MySQL 在顺序执行时,如果未对异常进行处理,总会将成功执行的的提交,而不会触发自动终止,但是我们可以在程序执行时进行放弃提交。

Redis 为什么没有回滚?

Redis 的官方文档给出了这样的解释

// 只有在使用错误的语法调用时才会失败Redis命令(并且在命令排队期间无法检测到问题),或者对于持有错误数据类型的键,Redis命令可能会失败:这意味着实际上失败的命令是编程错误的结果,以及在开发过程中很可能检测到的一种错误,而不是在生产中。

  • Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.

// Redis内部简化且速度更快,因为它不需要回滚的能力。

  • Redis is internally simplified and faster because it does not need the ability to roll back.

总结

数据库    自动回滚条件 操作错误 语法错误
MySQL
Redis

但是 MySQL 支持手动回滚,实际开发过程中可以自行手动对已提交的操作进行回滚操作,更加友好。

以上是MySQL和Redis事務的比較(圖文)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

MySQL的角色:Web應用程序中的數據庫 MySQL的角色:Web應用程序中的數據庫 Apr 17, 2025 am 12:23 AM

MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

docker怎麼啟動mysql docker怎麼啟動mysql Apr 15, 2025 pm 12:09 PM

在 Docker 中啟動 MySQL 的過程包含以下步驟:拉取 MySQL 鏡像創建並啟動容器,設置根用戶密碼並映射端口驗證連接創建數據庫和用戶授予對數據庫的所有權限

laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

解決數據庫連接問題:使用minii/db庫的實際案例 解決數據庫連接問題:使用minii/db庫的實際案例 Apr 18, 2025 am 07:09 AM

在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

laravel框架安裝方法 laravel框架安裝方法 Apr 18, 2025 pm 12:54 PM

文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

MySQL與其他編程語言:一種比較 MySQL與其他編程語言:一種比較 Apr 19, 2025 am 12:22 AM

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

MySQL與其他數據庫:比較選項 MySQL與其他數據庫:比較選項 Apr 15, 2025 am 12:08 AM

MySQL適合Web應用和內容管理系統,因其開源、高性能和易用性而受歡迎。 1)與PostgreSQL相比,MySQL在簡單查詢和高並發讀操作上表現更好。 2)相較Oracle,MySQL因開源和低成本更受中小企業青睞。 3)對比MicrosoftSQLServer,MySQL更適合跨平台應用。 4)與MongoDB不同,MySQL更適用於結構化數據和事務處理。

如何利用Redis緩存方案高效實現產品排行榜列表的需求? 如何利用Redis緩存方案高效實現產品排行榜列表的需求? Apr 19, 2025 pm 11:36 PM

Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...

See all articles