Işlemler içinde mysql işlemleri

6 Cevap php

Mysql veritabanı ile çalışan bir PHP komut dosyası, geçenlerde başka bir işlem içinde olması oldu bir noktada bir işlem kullanmak ihtiyaç vardı. Bütün testler bu cezası dışında çalıştığını göstermek gibi görünüyor, ama ben bu kullanımı üzerinde herhangi bir belge bulamıyorum.

Ben emin olmak istiyorum - işlemler mysql geçerli işlemler içindedir? Eğer öyleyse, derin iç içe işlemlerde kaç düzeyleri olduğunu öğrenmek için bir yolu var mı? (Yani kaç rollbacks normale dönmesi için alacağını)

Thanks in advance, Brian

6 Cevap

Contrary to everyone else's answer, you can effectively create transactions within transactions and it's really easy. You just create SAVEPOINT locations and use ROLLBACK TO savepoint to rollback part of the transaction, where savepoint is whatever name you give the savepoint. Link to MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/savepoint.html And of course, none of the queries anywhere in the transaction should be of the type that implicitly commit, or the whole transaction will be committed.

Örnekler:

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

PHP bu gibi bir kod yazdım, ve mükemmel çalışıyor:

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
}

I want to be sure - are transactions within transactions valid in mysql?

Hayır.

MySql iç içe geçmiş işlem desteklemez. Eğer olsa bunu taklit birkaç yolu vardır. İlk olarak, işlem biçimi olarak kayıt noktalarını kullanabilirsiniz, böylece size işlemler iki seviyelerini verir; Ben test için kullandım, ama üretim kodunda kullanmak eğer ben, sınırlamalar konusunda emin değilim. Daha basit bir çözüm, ikinci göz ardı begin transaction ve bunun yerine bir karşı artırmaktır. Her commit, bunu azaltmak için. Eğer sıfır isabet sonra, gerçek bir commit yapmak. Bu bariz sınırlamaları vardır; Örn. bir geri alma kabul edilebilir olduğunu, geri all işlemleri rulo, ancak yalnızca hata işleme için işlemler kullanmak bir durumda olacaktır.

Eğer test methadology kontrol etmek isteyebilirsiniz. Dışında MaxDB, MySQL uzaktan iç içe geçmiş işlemleri gibi bir şey desteklemiyor.

Bu konuya bazı büyük cevaplar sizin MySQL depolama motoru olarak InnoDB kullanmak ve MySQL 5.0.3 veya daha yüksek kullanıyorsanız, sizin açınızdan ya da herhangi bir ekstra çalışma için gerek kalmadan doğru dışarı kutunun iç içe geçmiş işlem olsun, ancak, vardır Bu Konuya başkaları tarafından tarif fantezi teknikleri herhangi bir.

From the MySQL docs on XA Transactions:

MySQL 5.0.3 ve üstü XA işlemler için sunucu tarafı desteği sağlar. Şu anda, bu destek InnoDB depolama motoru için kullanılabilir. XA Özellikler: MySQL XA uygulama X / Open CAE belge Distributed Transaction Processing dayanmaktadır. Bu belge Open Group tarafından yayınlanan ve http://www.opengroup.org/public/pubs/catalog/c193.htm de mevcuttur. Geçerli XA uygulanması Sınırlamaları "XA İşlemleri Kısıtlamalar", Bölüm E.5 açıklanmıştır.

My XA Transaction Example Just For You:

# Start a new XA transaction
XA START;

    # update my bank account balance, they will never know!
    UPDATE `bank_accounts` SET `balance` = 100000 WHERE `id` = 'mine';

    # $100,000.00 is a bit low, I'm going to consider adding more, but I'm not sure so 
    # I will start a NESTED transaction and debate it...
    XA START;

        # max int money! woo hoo!
        UPDATE `bank_accounts` SET `balance` = 2147483647 WHERE `id` = 'mine';

    # maybe thats too conspicuous, better roll back
    XA ROLLBACK;


# The $100,000 UPDATE still applies here, but the max int money does not, going for it!
XA COMMIT;

# Oh No!  Sirens!  It's the popo's!!! run!!
# What the hell are they using ints for money columns anyway!  Ahhhh!

XA İşlemler için MySQL Dokümantasyon:

I <3 XA Transactions 4 Eva!