MySQL Sorgu gecikme süresi / kilitlenme?

2 Cevap php

Paralel olarak çalışan birden çok PHP betikleri, her tekrar tekrar aynı tabloda aynı kayıt UPDATE sorgusu yapmak olduğunda, her sorgu ile tablo güncellenir önce bir 'gecikme süresi' olması için var mümkün mü?

Ben temelde paralel çalışan bir PHP script 5-6 örnekleri, cron üzerinden başlatılan edilerek oylandı. Her komut items tablodaki tüm kayıtları alır ve sonra içlerinden döngüler ve bunları işler.

Ancak, birden fazla kez aynı madde işleme önlemek için, ben ayrı bir tabloda işlenen son öğenin kimliğini saklamak. Yani bu benim kod nasıl işliyor:

function getCurrentItem()
{
  $sql = "SELECT currentItemId from settings";
  $result = $this->db->query($sql);
  return $result->get('currentItemId');
}

function setCurrentItem($id)
{
   $sql = "UPDATE settings SET currentItemId='$id'";
   $this->db->query($sql);
}

$currentItem = $this->getCurrentItem();

$sql = "SELECT * FROM items WHERE status='pending' AND id > $currentItem'";
$result = $this->db->query($sql);
$items = $result->getAll();

foreach ($items as $i)
{
   //Check if $i has been processed by a different instance of the script, and if so, 
   //leave it untouched.
   if ($this->getCurrentItem() > $i->id) 
     continue;

   $this->setCurrentItem($i->id);
   // Process the item here
}

Ama bütün önlemlere rağmen, çoğu ürün birden fazla işleniyor. Bana PHP komut dosyası tarafından yürütülüyor güncelleştirme sorguları biraz gecikme olduğunu düşündürüyor, ve veritabanı aslında kaydı güncelleştirir hangi zaman.

Bu doğru mu? Ve eğer öyleyse, ne diğer mekanizma ben PHP komut her zaman sadece son almak sağlamak için kullanması gereken currentItemId paralel çalışan birden çok komut vardır bile? Bir metin dosyası yerine db yardımıyla kullanarak misiniz?

2 Cevap

Bu buna paralel çalıştırmak ise yarış durumları önlemek için çok az önlem var.

script1:

getCurrentItem() yields Id 1234
...context switch to script2, before script 1 gets to run its update statement.

script2: 
getCurrentItem() yields Id 1234

Ve komut süreç Kimliği 1234 hem

Güncelleyebilir ve öğenin bir all-ya hiç çalışma durumunu kontrol etmek isterdim, sen ayarları masa gerekmez, ama bu (sözde kod) gibi bir şey yapmak istiyorum:

SELECT * FROM items WHERE status='pending' AND id > $currentItem

foreach($items as $i) {
 rows =  update items set status='processing' where id = $i->id and status='pending';
  if(rows == 0) //someone beat us to it and is already processing the item
    continue;
   process item..
 update items set status='done' where id = $i->id;
}

Neye ihtiyacınız edebilmek için herhangi bir iş parçacığı için:

  • Bekleyen bir öğeyi bulmak
  • o madde artık çalıştı ediliyor kaydı (settings tablosunda)

Ve bu yarım yoluyla müdahale başka bir iş parçacığı olmadan, tek seferde olanların hem de yapmak gerekiyor.

Ben bir stored procedure olarak tüm SQL sürülmesini tavsiye; o rakip parçacığı güvenli kılan tek bir işlem olarak tüm şey çalıştırmak mümkün olacak.