Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Transakcje MySQL w ramach transakcji

W przeciwieństwie do wszystkich odpowiedzi, możesz efektywnie tworzyć transakcje w ramach transakcji i jest to naprawdę proste. Po prostu tworzysz lokalizacje SAVEPOINT i używasz ROLLBACK TO savepoint do wycofania części transakcji, gdzie savepoint to nazwa, którą nadasz punktowi zapisu. Link do dokumentacji MySQL:http://dev.mysql.com/doc/refman/5.0/en/savepoint.html I oczywiście żadne z zapytań w dowolnym miejscu transakcji nie powinno być typu, który niejawnie zatwierdza, w przeciwnym razie zostanie zatwierdzona cała transakcja.

Przykłady:

START TRANSACTION;

# queries that don't implicitly commit

SAVEPOINT savepoint1;

# queries that don't implicitly commit

# now you can either ROLLBACK TO savepoint1, or just ROLLBACK to reverse the entire transaction.

SAVEPOINT savepoint2;

# queries that don't implicitly commit

# now you can ROLLBACK TO savepoint1 OR savepoint2, or ROLLBACK all the way.
# e.g.

ROLLBACK TO savepoint1;
COMMIT; # results in committing only the part of the transaction up to savepoint1

W PHP napisałem taki kod i działa on doskonale:

foreach($some_data as $key => $sub_array) {
  $result = mysql_query('START TRANSACTION'); // note mysql_query is deprecated in favor of PDO
  $rollback_all = false; // set to true to undo whole transaction
  for($i=0;$i<sizeof($sub_array);$i++) {
    if($sub_array['set_save'] === true) {
      $savepoint = 'savepoint' . $i;
      $result = mysql_query("SAVEPOINT $savepoint");
    }
    $sql = 'UPDATE `my_table` SET `x` = `y` WHERE `z` < `n`'; // some query/queries
    $result = mysql_query($sql); // run the update query/queries

    $more_sql = 'SELECT `x` FROM `my_table`'; // get data for checking
    $result = mysql_query($more_sql);

    $rollback_to_save = false; // set to true to undo to last savepoint
    while($row = mysql_fetch_array($result)) {
      // run some checks on the data
      // if some check says to go back to savepoint:
      $rollback_to_save = true; // or just do the rollback here.
      // if some check says to rollback entire transaction:
      $rollback_all = true;
    }
    if($rollback_all === true) {
      mysql_query('ROLLBACK'); // rollback entire transaction
      break; // break out of for loop, into next foreach
    }
    if($rollback_to_save = true) {
      mysql_query("ROLLBACK TO $savepoint"); // undo just this part of for loop
    }
  } // end of for loop
  mysql_query('COMMIT'); // if you don't do this, the whole transaction will rollback
}


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Uzyskaj ostatnio usunięty identyfikator w MySQL

  2. Łączenie MySQL z Visual Studio C#

  3. uzyskać sumę za limit w mysql przy użyciu tego samego zapytania?

  4. MYSQL sum() dla różnych wierszy

  5. Nie można połączyć się z lokalnym serwerem MySQL przez gniazdo '/var/mysql/mysql.sock' (38)