Maison  >  Article  >  base de données  >  Comparaison des transactions MySQL et Redis (image et texte)

Comparaison des transactions MySQL et Redis (image et texte)

不言
不言avant
2019-03-30 10:53:213403parcourir

Le contenu de cet article concerne la comparaison des transactions MySQL et Redis (images et textes). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

En bref : De manière générale, les transactions doivent remplir quatre conditions (ACID) : atomicité (Atomicité, ou indivisibilité), cohérence (Ccohérence), isolement ( Isolation, également appelée indépendance), durabilité (Durabilité).

À en juger par le titre, puisqu'il s'agit de deux affaires, quelle est la différence entre elles ? Dévoilons-les une par une, en commençant par les deux bases de données.

MySQL appartient à 关系型数据库 et Redis appartient à 非关系型数据库 Ils ont des interprétations différentes des transactions.

(Recommandations associées : Tutoriel MySQL, Tutoriel Redis)

Redis

[1] Les transactions Redis peuvent exécuter plusieurs transactions en une seule commande, et est livré avec les deux garanties importantes suivantes :

  • Les opérations par lots sont placées dans le cache de file d'attente avant d'envoyer la commande EXEC.
  • Entrez l'exécution de la transaction après avoir reçu la commande EXEC. Si une commande de la transaction ne parvient pas à s'exécuter, les commandes restantes sont toujours exécutées.
  • Pendant le processus d'exécution de la transaction, les demandes de commandes soumises par d'autres clients ne seront pas insérées dans la séquence de commandes d'exécution de la transaction.

Une transaction passera par les trois étapes suivantes du début à l'exécution :

  • Démarrer la transaction.
  • Commande pour rejoindre la file d'attente.
  • Exécutez la transaction.

L'exécution d'une seule commande Redis est atomique, mais Redis n'ajoute aucun mécanisme pour maintenir l'atomicité sur la transaction, donc l'exécution de la transaction Redis n'est pas atomique.

Une transaction peut être comprise comme un script d'exécution par lots packagé, mais les instructions par lots ne sont pas des opérations atomiques. L'échec d'une instruction au milieu n'entraînera pas l'annulation des instructions précédentes. Cela n’empêchera pas l’exécution des instructions suivantes.

Erreur d'opération

Cela semble un peu compliqué, alors exécutons-le et voyons les résultats.

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

Dans la transaction ci-dessus, une chaîne de données avec une clé de tr_1 est définie, puis des éléments sont ajoutés via lpush. C'est évidemment la mauvaise façon d'opérer lorsque nous soumettons A. 操作错误 apparaît lors de la transaction. Voyons maintenant la valeur de tr_1.

127.0.0.1:6379> get tr_1
"233"

Le contenu get obtenu via la commande tr_1 est toujours 233 et n'a pas changé. Jetons un coup d'œil aux autres.

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>

Ici, vous pouvez voir que tr_2 existe et la valeur est imprimée. À ce moment, nous avons constaté que même si 操作错误 est apparu, l'erreur n'a pas sans , provoquant l'arrêt de l'exécution. L'erreur Les instructions suivantes ont également été exécutées et exécutées avec succès Cela semble être conforme à ce qui précède L'échec d'une instruction au milieu n'entraînera pas l'annulation des instructions précédentes, cela n'empêchera pas non plus l'exécution des instructions suivantes.

Erreur de syntaxe

NON~, il y a une autre situation en ce moment语法错误

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)

Lorsque nous exécutons vers set, il n'y a pas Pour tous les paramètres, un paramètre est délibérément donné lors de la deuxième exécution. Vous pouvez voir que 语法错误 a été signalé et que la transaction a finalement été soumise, ce qui nous a également indiqué que la transaction avait été perdue en raison d'une erreur. Ensuite, nous avons utilisé keys * pour rechercher et avons constaté que c'était effectivement le cas.

Interprétation du document

Vous trouverez ici celles mentionnées dans le document officiel

Erreurs à l'intérieur d'une transaction

// Vous pouvez rencontrer lors exécution à deux erreurs de commande erronées.

Lors d'une transaction, il est possible de rencontrer deux types d'erreurs de commande :

// 1 La commande ne peut pas entrer dans la file d'attente, telles que : mauvais nombre de paramètres, mauvais nom de commande. ..., Ou certaines erreurs critiques telles qu'une mémoire insuffisante

  • Une commande peut ne pas être mise en file d'attente, il peut donc y avoir une erreur avant l'appel de EXEC. Par exemple, la commande peut être syntaxiquement incorrecte (fausse. nombre d'arguments, nom de commande incorrect, ...), ou il peut y avoir une condition critique comme une condition de mémoire insuffisante (si le serveur est configuré pour avoir une limite de mémoire à l'aide de la maxmemorydirective).

// 2. Opérations incorrectes sur les touches telles que l'utilisation de lpush sur les chaînes ci-dessus

  • Une commande peut échouer après EXEC est appelé, par exemple depuis que nous avons exécuté une opération sur une clé avec la mauvaise valeur (comme appeler une opération de liste sur une valeur de chaîne).

// Le client vérifie la commande tapée et la plupart du temps trouvera exec avant d'appeler it 🎜>Erreur. Si l'exécution de la commande renvoie QUEUED, cela signifie que la commande entre normalement dans la file d'attente, sinon, c'est une erreur dans la plupart des cas, le client terminera et abandonnera la transaction. 第一类

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元,即两步虽然很简单,简单走一下流程。

Comparaison des transactions MySQL et Redis (image et texte)

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

操作错误




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

Comparaison des transactions MySQL et Redis (image et texte)

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

语法错误

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

Comparaison des transactions MySQL et Redis (image et texte)

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer