MySQL Taahhüt edilen verilerin sorgu seçtiği görülmüyor


13

Bağlam: Kullanılan çerçeve İlkbahar'dır ve tüm sorgular JdbcTemplate ile çalıştırılır. Mysql Server sürümü 5.6.19'dur. tableBir olduğunu InnoDB tableve varsayılan gibi auto commityalıtım düzeyi tekrarlanabilir okunan ayarlanır ve.

Sorun : Bir Insertişlemin içinde gerçekleşen ve selecteklenen aynı verileri okuyan bir veri verileri görmüyor. selectİshal sonrasıinsert ve sonrası insertişlem vardır commited.

Ben mysql genel oturum yanı sıra bin günlüğü etkinleştirdim. Alakalı günlükler

Bin-log:

SET TIMESTAMP=1438265764/*!*/;
BEGIN
/*!*/;
# at 249935389
#150730 14:16:04 server id 1  end_log_pos 249935606 CRC32 0xa6aca292    Query   thread_id=40    exec_time=0     error_code=0
SET TIMESTAMP=1438265764/*!*/;
insert into user_geo_loc_latest(user_id, lat, lng) values(x,y,z) on duplicate key update lat=y, lng=z
/*!*/;
# at 249935606
#150730 14:16:06 server id 1  end_log_pos 249936255 CRC32 0x2a52c734    Query   thread_id=40    exec_time=0     error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table(txnid) VALUES ('885851438265675046')
/*!*/;
# at 249936255
#150730 14:16:06 server id 1  end_log_pos 249936514 CRC32 0x6cd85eb5    Query   thread_id=40    exec_time=0     error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table2(x) VALUES (y)
/*!*/;
# at 249936514
#150730 14:16:06 server id 1  end_log_pos 249936545 CRC32 0xceb9ec56    Xid = 9406873
COMMIT/*!*/;

Sorgu Günlüğü

150730 14:16:04    40 Query ...
....
40 Query     select count(*) from table where txnid = '885851438265675046'
                   40 Query     select @@session.tx_read_only
                   40 Query     INSERT INTO table(txnid) VALUES ('885851438265675046')
                   40 Query     select @@session.tx_read_only
                   40 Query     INSERT INTO table2(x) values(y)
                   40 Query     commit
....
150730 14:16:07    36 Query     select pp.*, b.create_date from table pp left join bill b on pp.bill_id = b.bill_id where pp.txnid = '885851438265675046'

İlginçtir ki, İlk insert(249935389) işlemin bir parçası olmamalıdır. Ayrı bir API çağrısıdır ve tamamen ilgisizdir. Bu işlem ile bahar karıştırma olabilir ya da günlüğü yanlış okuyorum? AFAIK aynı iş parçacığında olduğundan ekin işlemde olduğu anlamına gelir.

Sonraki ikisi insertsişlemin bir parçası ve işlem görüyor gibi görünüyor. (249.936.514). Şimdi seçme sorgusu (genel günlükte sonuncusu) işlemden sonra çalışır ve verileri görmez. 0 satır döndürür. Veriler dikkate alındığında bu nasıl olabilir committed? Yoksa commitiplik 40'da değil mi? İş parçacığı kimliği olmadığından.

Özetlemek gerekirse iki sorum var.

  1. Does BEGINönce binlog varlıkta INSERT INTO user_geo_loc(işlemin bir parçası değil), bu bahar / JDBC veya MySQL ile bir hata olduğunu basitçe işlemler onlar olmasa da bunu binlog yazılır gibi (bu işlem zaten işlediği bilir bunu yapar başarılı olur) ve bu nedenle asla geri alınmaz.

  2. Taahhüt, seçimden önce gerçekleştiği göz önüne alındığında (kesinleştirme 14:16:06 ve seçim 14:16:07 saatindedir), seçimin işlem tarafından eklenen satırı döndürmemesi nasıl olur?

Bu son derece şaşırtıcı. Herhangi bir yardım mutluluk duyacağız

Not: Bölme ve sorgu günlüğündeki sorgular hassas bilgileri kaldırmak için düzenlenmiştir. Ancak sorguların özü aynı kalır

Düzenleme: Ayrıntılı bir örnekle genel günlük ve sorgu günlüğü ile güncellendi.


5.5 olarak etiketlediniz, ancak 5.6'dan bahsettiniz; hangisi? Çoğaltma dahil mi?
Rick James

@RickJames üzgünüm, 5.6.19. Soruyu hem sorgu hem de bin günlüğündeki örnekle güncelledim. Ayrıca hiçbir çoğaltma yoktur Ben sadece hata ayıklama sorunu fark ettikten sonra bin günlüğü açık. Teşekkürler
Ahmed Aeon Axan

Teşekkürler, bu yardımcı olur. Bir BEGINveya görmüyorum START TRANSACTION. Bunun yerine kullanıyor autocommit=0musunuz? (Başlamayı tercih ederim ... taahhüt; işlemin kapsamını netleştirir.)
Rick James

Dolayısıyla çerçeve (bahar) işlemleri yönetir ve genellikle autocommit = 0 değerini ayarlar ve sonunda işlem yapar. Bağlantı zaten bu durumda olduğu için burada autocommit = 0 görmüyoruz sanırım.
Ahmed Aeon Axan

Yanıtlar:


3

İkinci soru hakkında bir hipotez yapmaya çalışıyorum:

Taahhüt, seçimden önce gerçekleştiği göz önüne alındığında (kesinleştirme 14:16:06 ve seçim 14:16:07 saatindedir), seçimin işlem tarafından eklenen satırı döndürmemesi nasıl olur?

İşlemler Bahar tarafından yönetilir. Böylece selectyayı çalıştırmadan önce start transactionbir başka bir sorgu çalıştırmak için bağlantıyı kullanmış olabilir veya zaten bağlantıyı kullanmış olabilir.

Bir tabloya ekleme taklit ilk oturum başlar t:

session1> create table t (i int auto_increment primary key);
Query OK, 0 rows affected (0,32 sec)

session1> insert into t values();
Query OK, 1 row affected (0,00 sec)

session1> select * from t;
+---+
| i |
+---+
| 1 |
+---+
1 row in set (0,00 sec)

session1> start transaction;
Query OK, 0 rows affected (0,00 sec)

session1> insert into t values();
Query OK, 1 row affected (0,00 sec)

Ben yeni bir oturum, oturum2, burada autocommit0 olarak ayarlanır. Bu yeni oturumda, bir seçim çalıştırılırken örtülü olarak bir işlem başlatılır.

session2> set autocommit = 0;
Query OK, 0 rows affected (0,00 sec)

session2> select * from t;  -- this starts a transaction
+---+
| i |
+---+
| 1 |
+---+
1 rows in set (0,00 sec)

Ekleme işlemini yürütmek için session1 öğesine gidin.

session1> commit;

Şimdi tekrar session2'ye geçin:

session2> select * from t;
+---+
| i |
+---+
| 1 |
+---+
1 row in set (0,00 sec)

Oturum2 yeni eklenen satırı göremiyor. commitSession2 içinde a yükseltilirse, session1 içine yeni satır eklendiğini görebiliriz

session2> commit
1 row in set (0,00 sec)

session2> select * from t;
+---+
| i |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0,00 sec)

Genel günlük şöyle görünür:

150804 14:04:10     2 Query select * from t

150804 14:04:30     1 Query start transaction
150804 14:04:39     1 Query insert into t values ()
150804 14:04:44     1 Query commit
150804 14:04:51     2 Query select * from t

150804 14:05:07     2 Query commit
150804 14:05:10     2 Query select * from t

İlk satır oturum 2 ile ilgilidir. Oturum 2 işlemi açtığındadır.

Sizin durumunuzda bunun olup olmadığını bilmiyorum. Connection_id 36'nın başka sorgular için kullanılıp kullanılmadığını genel günlüğünüzde kontrol edebilirsiniz. Bilmemize izin ver.

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.