Bu iki sorgu, sırayla yürütülürse kilitlenmeye neden olur mu?


12

Bu kesinlikle diğer sorumun sebebi , ama aşağıdaki günlüğe dayalı bir hipotezim olduğu için ikisini ayırmaya değer olduğunu düşündüm.

Benim hipotezim, diğer kilitlenmenin aslında aşağıdaki sorguların bir sonucu olduğu, orijinal sorgu innodb durumunu sadece en son işlemleri gösterdiğine göre gizlendiğinde (bu doğru mu?).

Günlüğe dayanarak, kodumuzu kontrol ettim ve aşağıdaki iki sorguyu sırayla yürüttüm:

db.Execute("UPDATE people SET iphone_device_id=NULL WHERE iphone_device_id=@0 AND people_id<>@1", DeviceID, m_User.people_id);
// I have hard coded this query in this snippet to simplify things
db.Execute("UPDATE people SET company_id = 444, name = 'Dad', password = '<pass>', temp_password = NULL, reset_password_hash = NULL, email = '<redacted>@gmail.com', phone = NULL, mobile = NULL, iphone_device_id = 'iphone:<device_id_blah>', iphone_device_time = '2011-06-06 19:12:29', last_checkin = '2011-06-07 02:49:47', location_lat = <lat>, location_long = <lng>, gps_strength = 66, picture_blob_id = 1661, authority = 1, active = 1, date_created = '2011-03-20 19:18:34', last_login = '2011-06-07 11:15:01', panic_mode = 0, battery_level = 0.55, battery_state = 'unplugged' WHERE people_id = 666");

Burada db.Execute temel olarak bir System.Data DbCommand nesnesinde bir ExecuteNonQuery yapıyor .

Bu sorgu dizisi bir kilitlenmeyle sonuçlanacak mı? Benim hipotezim, iki sorgudaki iki farklı saha düzeninin soruna neden olduğudur. Kilitlenmeyi gidermek için iki sorguyu bir işlemde tamamlayabilir miyim?

------------------------
LATEST DETECTED DEADLOCK
------------------------
110607 11:15:01
*** (1) TRANSACTION:
TRANSACTION 0 45674214, ACTIVE 0 sec, OS thread id 2584 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1216, 2 row lock(s)
    MySQL thread id 109, query id 4044915 localhost 127.0.0.1 famdev Searching rows for update
    UPDATE people SET iphone_device_id=NULL WHERE iphone_device_id='iphone:<device_id_blah>' AND people_id<>666
    *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
    RECORD LOCKS space id 0 page no 4611 n bits 152 index `PRIMARY` of table `family`.`people` trx id 0 45674214 lock_mode X locks rec but not gap waiting
    Record lock, heap no 7 PHYSICAL RECORD: n_fields 25; compact format; info bits 0
    0: len 8; hex 8000000000000941; asc        A;; 1: len 6; hex 000002b8eedf; asc       ;; 2: len 7; hex 00000002801064; asc       d;; 3: len 8; hex 80000000000004c6; asc         ;; 4: len 3; hex 446164; asc Dad;; 5: len 30; hex <data0>; asc <data1>;...(truncated); 6: SQL NULL; 7: SQL NULL; 8: len 17; hex <data2>; asc <redacted>@gmail.com;; 9: SQL NULL; 10: SQL NULL; 11: len 30; hex <data3>; asc iphone:<data4>;...(truncated); 12: len 8; hex <data5>; asc    J]  };; 13: len 8; hex <data6>; asc    J]   ;; 14: len 8; hex <data7>; asc ~t  g C@;; 15: len 8; hex <data8>; asc G  I &S ;; 16: len 2; hex 8042; asc  B;; 17: len 8; hex <data9>; asc        };; 18: len 4; hex <data10>; asc     ;; 19: len 1; hex 81; asc  ;; 20: len 8; hex <data11>; asc    JL} Z;; 21: len 8; hex <data12>; asc    J]  M;; 22: len 1; hex 80; asc  ;; 23: len 8; hex <data13>; asc        ?;; 24: len 9; hex <data14>; asc unplugged;;

    *** (2) TRANSACTION:
    TRANSACTION 0 45674209, ACTIVE 0 sec, OS thread id 3804 starting index read, thread declared inside InnoDB 500
    mysql tables in use 1, locked 1
    5 lock struct(s), heap size 1216, 2 row lock(s), undo log entries 1
    MySQL thread id 110, query id 4044916 localhost 127.0.0.1 famdev Updating
    UPDATE people SET company_id = 444, name = 'Dad', password = '<pass>', temp_password = NULL, reset_password_hash = NULL, email = '<redacted>@gmail.com', phone = NULL, mobile = NULL, iphone_device_id = 'iphone:<device_id_blah>', iphone_device_time = '2011-06-06 19:12:29', last_checkin = '2011-06-07 02:49:47', location_lat = <lat>, location_long = <lng>, gps_strength = 66, picture_blob_id = 1661, authority = 1, active = 1, date_created = '2011-03-20 19:18:34', last_login = '2011-06-07 11:15:01', panic_mode = 0, battery_level = 0.55, battery_state = 'unplugged' WHERE people_id = 666
    *** (2) HOLDS THE LOCK(S):
        RECORD LOCKS space id 0 page no 4611 n bits 152 index `PRIMARY` of table `family`.`people` trx id 0 45674209 lock mode S locks rec but not gap
        Record lock, heap no 7 PHYSICAL RECORD: n_fields 25; compact format; info bits 0
        0: len 8; hex 8000000000000941; asc        A;; 1: len 6; hex 000002b8eedf; asc       ;; 2: len 7; hex 00000002801064; asc       d;; 3: len 8; hex 80000000000004c6; asc         ;; 4: len 3; hex 446164; asc Dad;; 5: len 30; hex <data0>; asc <data1>;...(truncated); 6: SQL NULL; 7: SQL NULL; 8: len 17; hex <data2>; asc <redacted>@gmail.com;; 9: SQL NULL; 10: SQL NULL; 11: len 30; hex <data3>; asc iphone:<data4>;...(truncated); 12: len 8; hex <data5>; asc    J]  };; 13: len 8; hex <data6>; asc    J]   ;; 14: len 8; hex <data7>; asc ~t  g C@;; 15: len 8; hex <data8>; asc G  I &S ;; 16: len 2; hex 8042; asc  B;; 17: len 8; hex <data9>; asc        };; 18: len 4; hex <data10>; asc     ;; 19: len 1; hex 81; asc  ;; 20: len 8; hex <data11>; asc    JL} Z;; 21: len 8; hex <data12>; asc    J]  M;; 22: len 1; hex 80; asc  ;; 23: len 8; hex <data13>; asc        ?;; 24: len 9; hex <data14>; asc unplugged;;

        *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
        RECORD LOCKS space id 0 page no 4611 n bits 152 index `PRIMARY` of table `family`.`people` trx id 0 45674209 lock_mode X locks rec but not gap waiting
        Record lock, heap no 7 PHYSICAL RECORD: n_fields 25; compact format; info bits 0
        0: len 8; hex 8000000000000941; asc        A;; 1: len 6; hex 000002b8eedf; asc       ;; 2: len 7; hex 00000002801064; asc       d;; 3: len 8; hex 80000000000004c6; asc         ;; 4: len 3; hex 446164; asc Dad;; 5: len 30; hex <data0>; asc <data1>;...(truncated); 6: SQL NULL; 7: SQL NULL; 8: len 17; hex <data2>; asc <redacted>@gmail.com;; 9: SQL NULL; 10: SQL NULL; 11: len 30; hex <data3>; asc iphone:<data4>;...(truncated); 12: len 8; hex <data5>; asc    J]  };; 13: len 8; hex <data6>; asc    J]   ;; 14: len 8; hex <data7>; asc ~t  g C@;; 15: len 8; hex <data8>; asc G  I &S ;; 16: len 2; hex 8042; asc  B;; 17: len 8; hex <data9>; asc        };; 18: len 4; hex <data10>; asc     ;; 19: len 1; hex 81; asc  ;; 20: len 8; hex <data11>; asc    JL} Z;; 21: len 8; hex <data12>; asc    J]  M;; 22: len 1; hex 80; asc  ;; 23: len 8; hex <data13>; asc        ?;; 24: len 9; hex <data14>; asc unplugged;;

Yanıtlar:


7

İfadeler sırayla yürütülse de, aynı işlem içinde mevcutlarsa, sorgular arasında bir tür kontrol noktası vermeli veya işleme başlamadan önce işlem yalıtım düzeyini tweek etmelisiniz .

Tx_isolation için dört değer vardır:

İşlem yalıtımını üç (3) yolla ayarlayabilirsiniz:

Bunu /etc/my.cnf dosyasına yazın ve mysql'yi yeniden başlatın

[mysqld]
autocommit=0
transaction-isolation = READ-UNCOMMITTED

veya yeni bir işleme başlamadan önce DB Bağlantısının içinde ayarlayabilirsiniz:

db.Execute("SET tx_isolation = 'READ-UNCOMMITTED'");
db.Execute("SET autocommit = 0");

protokollerini kullanarak otomatik komutu devre dışı bırakma veya devre dışı bırakma (Yasal Uyarı: Ben bir .NET geliştiricisi değilim)

"Kirli okumalara" izin vermek için READ-UNCOMMITTED'e doğru eğilmeme rağmen, hangisinin istenen etkiye sahip olduğunu görmek için bir noktada diğer işlem yalıtım düzeylerini denemelisiniz.

Bir şans ver !!!


4

Bu iki sorgunun en azından yaşadığımız sorunun bir parçası olduğu ortaya çıktı. Bu iki sorguyu şu kişilerden değiştirdik:

db.Execute("UPDATE people SET iphone_device_id=NULL WHERE iphone_device_id=@0 AND people_id<>@1", DeviceID, m_User.people_id);
db.Execute("UPDATE people SET company_id = 444, name = 'Dad', password = '<pass>', temp_password = NULL, reset_password_hash = NULL, email = '<redacted>@gmail.com', phone = NULL, mobile = NULL, iphone_device_id = 'iphone:<device_id_blah>', iphone_device_time = '2011-06-06 19:12:29', last_checkin = '2011-06-07 02:49:47', location_lat = <lat>, location_long = <lng>, gps_strength = 66, picture_blob_id = 1661, authority = 1, active = 1, date_created = '2011-03-20 19:18:34', last_login = '2011-06-07 11:15:01', panic_mode = 0, battery_level = 0.55, battery_state = 'unplugged' WHERE people_id = 666");

için:

db.Execute("UPDATE people SET iphone_device_id=NULL WHERE iphone_device_id=@0 AND people_id<>@1", DeviceID, m_User.people_id);
db.Execute("UPDATE people SET iphone_device_id=@0, iphone_device_time=@1, last_login=@1 WHERE people_id=@2", DeviceID, System.DateTime.UtcNow, m_User.people_id);

Dolayısıyla artık tüm kaydı (birden fazla tuşta) güncellemiyoruz ve alanları aynı sırada güncelliyoruz. Değişikliği yaptığımızdan beri kilitlenmelerimiz kayboldu.

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.