Heim  >  Artikel  >  Datenbank  >  Vergleich von MySQL- und Redis-Transaktionen (Bild und Text)

Vergleich von MySQL- und Redis-Transaktionen (Bild und Text)

不言
不言nach vorne
2019-03-30 10:53:213404Durchsuche

Der Inhalt dieses Artikels befasst sich mit dem Vergleich von MySQL- und Redis-Transaktionen (Bilder und Texte). Ich hoffe, dass er für Sie hilfreich ist.

Kurz gesagt: Im Allgemeinen müssen Transaktionen vier Bedingungen (ACID) erfüllen: Atomizität (ATomizität oder Unteilbarkeit), Konsistenz (CKonsistenz), Isolation ( ISolation, auch Unabhängigkeit genannt), Dauerhaftigkeit (DDurabilität).

Was ist dem Titel nach zu urteilen, da es sich bei beiden um Affären handelt, was ist der Unterschied zwischen ihnen? Lassen Sie uns sie einzeln entschlüsseln, beginnend mit den beiden Datenbanken.

MySQL gehört zu 关系型数据库 und Redis gehört zu 非关系型数据库. Sie haben unterschiedliche Interpretationen von Transaktionen.

(Verwandte Empfehlungen: MySQL-Tutorial, Redis-Tutorial)

Redis

[1] Redis-Transaktionen können mehrere Transaktionen ausführen auf einmal und verfügt über die folgenden zwei wichtigen Garantien:

  • Batch-Vorgänge werden in den Warteschlangen-Cache gestellt, bevor der EXEC-Befehl gesendet wird.
  • Starten Sie die Transaktionsausführung nach dem Empfang des EXEC-Befehls. Wenn ein Befehl in der Transaktion nicht ausgeführt werden kann, werden die verbleibenden Befehle trotzdem ausgeführt.
  • Während des Transaktionsausführungsprozesses werden von anderen Clients übermittelte Befehlsanforderungen nicht in die Befehlssequenz zur Transaktionsausführung eingefügt.

Eine Transaktion durchläuft vom Start bis zur Ausführung die folgenden drei Phasen:

  • Transaktion starten.
  • Befehl zum Beitreten zur Warteschlange.
  • Führen Sie die Transaktion aus.

Die Ausführung eines einzelnen Redis-Befehls ist atomar, aber Redis fügt keinen Mechanismus zur Aufrechterhaltung der Atomizität der Transaktion hinzu, sodass die Ausführung der Redis-Transaktion nicht atomar ist.

Eine Transaktion kann als gepacktes Batch-Ausführungsskript verstanden werden, aber Batch-Anweisungen sind keine atomaren Operationen. Der Fehler einer Anweisung in der Mitte führt nicht zum Rollback der vorherigen Anweisungen. Es führt nicht dazu, dass nachfolgende Anweisungen nicht ausgeführt werden.

Bedienungsfehler

Es scheint etwas kompliziert zu sein, also führen wir es tatsächlich aus und sehen uns das Ergebnis an.

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

In der obigen Transaktion werden Zeichenfolgendaten mit dem Schlüssel tr_1 festgelegt und dann werden Elemente über lpush hinzugefügt. Dies ist offensichtlich die falsche Vorgehensweise, wenn wir die Transaktion A übermitteln 操作错误 erscheint. Schauen wir uns nun den Wert von tr_1 an.

127.0.0.1:6379> get tr_1
"233"

Der durch den get-Befehl erhaltene tr_1-Inhalt ist immer noch 233 und hat sich nicht geändert.

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>

Hier können Sie sehen, dass tr_2 vorhanden ist und der Wert gedruckt wird. Zu diesem Zeitpunkt haben wir festgestellt, dass der Fehler nicht 操作错误ohne aufgetreten ist, obwohl aufgetreten ist Die Ausführung wird gestoppt. Die Anweisung wurde ebenfalls erfolgreich ausgeführt. Es scheint nicht mit dem oben genannten übereinzustimmen dazu führen, dass die nachfolgenden Anweisungen nicht ausgeführt werden.

Syntaxfehler

NEIN~, derzeit liegt eine andere Situation vor语法错误

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)

Wenn wir set ausführen, werden keine Parameter angegeben. Bei der zweiten Ausführung wurde bewusst ein Parameter angegeben. Sie können sehen, dass 语法错误 gemeldet und die Transaktion schließlich übermittelt wurde, was uns auch mitteilte, dass die Transaktion aufgrund eines Fehlers verloren gegangen ist. Dann haben wir mit keys * gesucht und festgestellt, dass dies tatsächlich der Fall war.

Dokumentinterpretation

Hier finden Sie diejenigen, die im offiziellen Dokument erwähnt werden

Fehler innerhalb einer Transaktion

// Sie können währenddessen auftreten Ausführung zu zwei falschen Befehlsfehlern.

Während einer Transaktion können zwei Arten von Befehlsfehlern auftreten:

// 1 Der Befehl kann nicht in die Warteschlange gelangen, wie zum Beispiel: falsche Anzahl von Parametern, falscher Befehlsname ... oder einige kritische Fehler wie unzureichender Speicher

  • Ein Befehl kann möglicherweise nicht in die Warteschlange gestellt werden, sodass möglicherweise ein Fehler auftritt, bevor EXEC aufgerufen wird. Beispielsweise ist der Befehl möglicherweise syntaktisch falsch (falsch). Anzahl der Argumente, falscher Befehlsname usw.) oder es liegt möglicherweise ein kritischer Zustand vor, z. B. nicht genügend Speicher (wenn der Server mithilfe der maxmemory-Anweisung so konfiguriert ist, dass er ein Speicherlimit hat).

// 2. Falsche Operationen an Schlüsseln, wie z. B. die Verwendung von lpush für die oben genannten Zeichenfolgen

  • Ein Befehl schlägt möglicherweise fehl, nachdem EXEC aufgerufen wurde, zum Beispiel seit wir ausgeführt haben eine Operation für einen Schlüssel mit dem falschen Wert (wie das Aufrufen einer Listenoperation für einen Zeichenfolgenwert).

// Der Client überprüft den eingegebenen Befehl und findet meistens exec vor dem Aufruf it 🎜>Fehler. Wenn die Befehlsausführung QUEUED zurückgibt, bedeutet dies, dass der Befehl normal in die Warteschlange gelangt. Andernfalls wird der Client die Transaktion beenden und abbrechen. 第一类

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.

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

MySQL

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

测试表结构 user

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

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

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

Vergleich von MySQL- und Redis-Transaktionen (Bild und Text)

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

操作错误




类型 注释
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;

Vergleich von MySQL- und Redis-Transaktionen (Bild und Text)

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

语法错误

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

Vergleich von MySQL- und Redis-Transaktionen (Bild und Text)

答案:不会,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 支持手动回滚,实际开发过程中可以自行手动对已提交的操作进行回滚操作,更加友好。

Das obige ist der detaillierte Inhalt vonVergleich von MySQL- und Redis-Transaktionen (Bild und Text). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen