108 votes

Les transactions imbriquées sont-elles autorisées dans MySQL?

Est-ce que MySQL permet l'utilisation de transactions imbriquées ?

6 votes

Mysql ne prend pas en charge les transactions imbriquées

90voto

Quassnoi Points 191041

Non, mais

InnoDB prend en charge les SAVEPOINTS.

Vous pouvez faire ce qui suit:

CREATE TABLE t_test (id INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;

START TRANSACTION;

INSERT
INTO    t_test
VALUES  (1);

SELECT  *
FROM    t_test;

 id
---
  1

SAVEPOINT tran2;

INSERT
INTO    t_test
VALUES  (2);

SELECT  *
FROM    t_test;

 id
---
  1
  2

ROLLBACK TO tran2;

SELECT  *
FROM    t_test;

 id
---
  1

ROLLBACK;

SELECT  *
FROM    t_test;

 id
---

33 votes

Ce n'était pas la question, les "savepoints" sont une chose, le support des "transactions imbriquées" était la vraie question. Voir ce lien

2 votes

@arod : pourriez-vous s'il vous plaît expliquer la différence dans un contexte monofil ? Merci !

0 votes

@Quassnoi Je crois que les commandes émises à la base de données sont différentes, n'est-ce pas? Je pourrais me tromper

61voto

bancer Points 4187

À partir de la documentation MySQL :

Les transactions ne peuvent pas être imbriquées. C'est une conséquence de l'engagement implicite effectué pour toute transaction en cours lorsque vous lancez une instruction START TRANSACTION ou l'un de ses synonymes. https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

6voto

Jalal El-Shaer Points 6027

En fait, ils ont commencé à faire :

Les portées de transaction imbriquées n'étaient pas prises en charge. MySQL Connector/NET 6.3.xx implémente désormais des portées de transaction imbriquées. Une pile de portées par thread est maintenue, ce qui est nécessaire pour gérer les portées imbriquées avec les options RequiresNew ou Suppress.

http://dev.mysql.com/doc/refman/5.5/fr/connector-net-news-6-3-0.html

-5voto

Offenso Points 44

Si vous utilisez php, alors vous pourriez être intéressé par https://github.com/Enelar/phpsql Il prend en charge mysql et pgsql, et est extensible à d'autres connecteurs.

function TransferMoney()
{ // Le code de transaction imbriqué ne pourrait même pas savoir qu'il est imbriqué
  $trans3 = db::Begin();
  if (!db::Query("--Retirer de l'argent de l'utilisateur", [$uid, $amount], true))
    return $trans3->Rollback();
  db::Query("--Déposer de l'argent dans le système");
  return $trans3->Commit();
}

$trans = db::Begin();
db::Query("--Donner l'objet à l'inventaire de l'utilisateur");
    $trans2 = $trans->Begin();
    $trans2->Query("--Essayer quelques actions puis décider de faire un rollback");
    $trans2->Rollback();
// Commit ou rollback en fonction du résultat du transfert d'argent
return $trans->Finish(TransferMoney());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X