Ağ bağlantısını kesmek bir sorguyu durdurur mu?


13

Geçenlerde 100.000 kayda karşı bir güncelleme sorgusu yürüttüm. Sorgu çalışırken bir hata yapmış olduğumu fark ettim ve hızlı bir şekilde ağ kablosunu çıkarın.

Güncelleme sorgusu

  1. işlemeyi durdur ve tamamen geri al?
  2. işleme tamamlanıp tamamlanmaya devam edilsin mi?
  3. işlemeyi durdurun ve hedef satırların yalnızca bir kısmını güncel mi bırakın?

2
bir sorgu sunucuya vurduğunda, sorgu sunucuda iptal edilmedikçe devam eder.
JP Chauhan


1
Martin'in yorumu, sorunuza doğrudan cevap verir, robocop. Ağ , sorgunuzun çalışması tamamlanmadan önce SQL Server bağlantısını kesildiğini bildirirse , SQL Server geri alır. Aksi takdirde, sorgu SQL Server'ın bir ağ bağlantısının kesilmediği söylenmeden önce tamamlanırsa, işlenecektir. Hiçbir durumda (tek bir güncelleme sorgusu yazdığınız varsayılarak) SQL Server kısmi bir güncelleme yürütmez.
Nick Chammas

Yanıtlar:


22

Nick ve Martin tarafından belirtildiği gibi, sorgunuzun nihai durumu, SQL Server'ın sorgu tamamlanmadan önce ağ kablosu çekme hakkında bilgi sahibi olup olmadığına bağlıdır. Gönderen Books Online (Ben bunun için eşdeğer konular içinde olduğunu ilginç bulduğu halde 2000 , 2005 , 2008 ve 2008 R2 değil 2012 veya 2014 ama):

Bir hata, işlemin başarıyla tamamlanmasını engelliyorsa, SQL Server işlemi otomatik olarak geri alır ve işlem tarafından tutulan tüm kaynakları serbest bırakır. İstemcinin Veritabanı Altyapısı örneğine ağ bağlantısı kesilirse, ağ kopma örneğini bildirdiğinde, bağlantının bekleyen tüm işlemleri geri alınır. İstemci uygulaması başarısız olursa veya istemci bilgisayar kapanırsa veya yeniden başlatılırsa, bu da bağlantıyı keser ve Veritabanı Altyapısı örneği, ağ kesintiyi bildirdiğinde bekleyen tüm bağlantıları geri alır. İstemci uygulama oturumunu kapatırsa, bekleyen tüm işlemler geri alınır.

(Bir kenara, son cümledeki kelime bağlantıları muhtemelen işlemler anlamına geliyordu . Bir kişinin bağlantıyı nasıl geri aldığını bilmiyorum.)

Benzer şekilde, SQL Server, beklenmedik bir şekilde kapatıldıktan sonra kurtarma sırasında işlemleri geri alabilir veya yineleyebilir ve bu, kapatma anındaki işlemin durumuna bağlı olacaktır. İnsanların bu taktiği, yapmaya çalıştığınız şeyi (işlemleri iptal etmek için) kullandıklarını gördüm ve sunucu yeniden başladığında işin çoğu basitçe yeniden yapıldı (bu yüzden diz-pislik reaksiyonunun net etkisi çok daha yakındı beklediklerinden sıfıra).

Buna tabi olmak yerine, bir ağ kablosunun sorulması veya makinenin kapatılması gibi panik içinde sert şeyler yapmak yerine, gelecekte önemli sistemlere karşı geçici sorgular yürütme konusunda daha iyi bir disipline sahip olmanızı öneririm. Örneğin:

UPDATE dbo.sometable 
-- where *oops* I forgot this part

Al bunu:

BEGIN TRANSACTION;

UPDATE dbo.sometable
-- where *oops* I forgot this part

-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;

Ardından, güncelleme gerçekten doğruysa, COMMITparçayı vurgulayıp çalıştırabilirsiniz. Değilse , parçayı sakin bir şekilde vurgulayabilir ROLLBACKve çalıştırabilirsiniz. Şablonunuzu bu ortak metni içerecek şekilde düzenlemek için SSMS Araçlar Paketi gibi eklentileri bile kullanabilirsiniz New Query.

Şimdi yine sorguyu çalıştırın ve sonra da bu olay derde olabilir yok şimdi işlem diğer kullanıcıları engellediği için, ya geri alma taahhüt veya. Ancak bu, verileri değiştirilemez bir şekilde değiştirmekten daha iyidir.

Ve elbette, her zaman olduğu gibi, güvenebileceğiniz bir yedeğiniz var.


5
Bu mükemmel bir tavsiye ve OP sorununun kökünü ele alıyor, ancak aslında sorgunun çalışmaya devam edip etmediği sorusuna cevap vermiyor.
Nick Chammas

3
@Nick, motivasyonum semptomu değil, soruyu (soruyu teşvik eden) ele almaktı, ancak cevabımı güncelledim.
Aaron Bertrand

8

@Aaron doğru. Komutlarınızdan önce bir işlem oluşturmak en iyi seçenektir. Bunu yapmayı hatırlayamıyorsanız, seçeneklerden biri Tools-Optionsayara gitmek ve açmaktır SET IMPLICIT_TRANSACTIONS. Bu, belirli komutlar çalıştırıldığında otomatik olarak bir işlem başlatır. Bu UPDATE, DELETEvb içerir "change". SELECTayrıca listeye dahil edilir ve willbir işlem başlatır. Bir işlem başlatan komutların tam listesini burada bu ayar göreceksiniz . Önceden başlatılmışsa, bir işlem oluşturmaz. Şimdi bunun aşağı tarafı, COMMITherhangi bir değişiklikten sonra hatırlamanız gerekecek .

NOT: @ Aaron'un önerisine dayanarak bunu yeniden vurgulayacağım.

This is very important!  You will have to remember to COMMIT after any change made!

Temelde, BEGINbir işlemi unutmak ve bir şeyi karıştırmak, COMMITbir işlemi unutmak ve açık bırakıp gün için ayrılırsanız asılmasını sağlamak için işlem yapıyorsunuz. İşlemimi geri alacağını düşünerek sadece bir sorgu penceresini kapatarak test yaptım, ancak işlemi işlemek veya geri almak istedim.

resim açıklamasını buraya girin


Aslında: SELECT olacaktır (ayrıca haberi bağlantı belgelenmiştir) bir hareketi başlatmak
a_horse_with_no_name

@ A_horse_with_no_name yakaladığınız için teşekkürler! Yeterince dikkatle okumadım ve eski bir hafızadan çıkıyordum (bu yanlıştı).
Kenneth Fisher

1
Bu yararlı bir gönderi, ancak aslında sorgunun sorgunun devam edip etmediği sorusuna cevap vermez.
Nick Chammas

2
@ Aaron'un cevabına bir ekleme olarak kastedildi. Sadece bir yorum koymak için çok oldu.
Kenneth Fisher

2

gerçekten bağlı olduğunu düşünüyorum:

ağ kablosunu çıkarmadan önce komut zaten sunucuya ulaşırsa, komut yine de normal şekilde çalışmaya devam eder.

tüm güncelleme komutlarını kapsüllemek için bir TransactionScope (.Net içinde kullanılır, diğer dillerden emin değilsiniz) varsa, muhtemelen yalnızca transactionScope.Complete () yürütülmediği, ancak hiçbir garanti alınmadığı takdirde işlemin durdurulmasını durdurabilirsiniz. .


2
"Komut ağ kablosunu çıkarmadan önce sunucuya zaten ulaşırsa, komut yine de normal şekilde çalışmaya devam eder." Bu, Martin'in yukarıda bağlandığı SQL Server BOL sayfası ile çelişmektedir . Bkz. "İşlem İşlemi Sırasındaki Hatalar" .
Nick Chammas

Haklısın. bir işlem belirtildiğinde, komut otomatik olarak geri alınır. ancak deneyimlediğimiz gibi, hiçbir işlem açıkça belirtilmediğinde, komutumuzu (işlemsiz toplu güncelleme) tam olarak yürütüldü, hatta başvurumuzu ortada durdurduk, aslında bağlantıyı kesti - ama gerçekten zamanlama olarak iyi bir örnek değil muhtemelen doğru değildi. muhtemelen bunun için bazı testler yapmak iyidir
Rex
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.