MySQL कमिटेड डेटा क्वेरी का चयन करने के लिए नहीं देखा गया


13

संदर्भ: उपयोग की गई रूपरेखा स्प्रिंग है और सभी प्रश्न JdbcTemplate के साथ चलाए जाते हैं। मैसूर सर्वर संस्करण 5.6.19 है। tableएक है InnoDB tableऔर चूक की तरह auto commitऔर अलगाव स्तर repeatable-पढ़ने के लिए निर्धारित है।

समस्या : एक Insertलेनदेन के अंदर होता है और selectजो एक ही डेटा सम्मिलित करता है वह डेटा नहीं देखता है। selectरन के बादinsert और बाद insertलेन-देन हुआ commited

मैंने बिन लॉग और साथ ही mysql में सामान्य लॉग सक्षम किया है। प्रासंगिक लॉग नीचे

बिन-लॉग:

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/*!*/;

क्वेरी लॉग

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'

उत्सुकता से, पहले insert(249935389) लेनदेन का हिस्सा बिल्कुल नहीं होना चाहिए। यह एक अलग एपीआई कॉल और पूरी तरह से असंबंधित है। यह लेन-देन के साथ वसंत का मिश्रण हो सकता है या मैं लॉग को गलत पढ़ रहा हूं? AFAIK के बाद से यह एक ही धागे पर है इसका मतलब यह है कि लेनदेन लेनदेन में है।

अगले दो insertsलेन-देन का हिस्सा हैं और ऐसा लगता है कि यह कमिट करता है। (249,936,514)। अब चयन क्वेरी (सामान्य लॉग में अंतिम) कमिट के बाद चलती है और यह डेटा नहीं देखती है। यह 0 पंक्तियों को लौटाता है। डेटा को देखते हुए ऐसा कैसे हो सकता है committed? या commitधागा 40 पर नहीं है? चूंकि इसमें थ्रेड आईडी नहीं है।

संक्षेप में, मेरे दो प्रश्न हैं।

  1. क्या BEGINबिनलॉग से पहले होता है INSERT INTO user_geo_loc(जो लेन-देन का हिस्सा नहीं है), क्या यह वसंत / Jdbc या MySql के साथ एक बग है, जैसा कि यह जानता है कि यह लेनदेन पहले से ही प्रतिबद्ध है (क्योंकि लेन-देन के बारे में लिखा है सफल) और इसलिए कभी पीछे नहीं हटेगा।

  2. यह देखते हुए कि कमिट से पहले होता है (कमेटी 14:16:06 पर है और सेलेक्ट 14:16:07 पर है) यह कैसे होता है कि सेलेक्शन ट्रांजेक्शन द्वारा डाली गई पंक्ति को वापस नहीं करता है?

यह बेहद हैरान करने वाला है। किसी भी सहायता की सराहना की जाएगी

नोट: संवेदनशील जानकारी को निकालने के लिए बिन और क्वेरी लॉग दोनों में प्रश्नों को संपादित किया गया है। लेकिन प्रश्नों का सार वही रहता है

संपादित करें: सामान्य लॉग और क्वेरी लॉग के साथ विस्तृत उदाहरण के साथ अपडेट किया गया।


आपने इसे ५.५ का टैग दिया, लेकिन ५.६ का उल्लेख किया; यह किसका है? प्रतिकृति शामिल है?
रिक जेम्स

@RickJames क्षमा करें, यह 5.6.19 है। मैंने प्रश्न को क्वेरी और बिन लॉग दोनों से उदाहरण के साथ अद्यतन किया है। इसके अलावा इसमें कोई प्रतिकृति शामिल नहीं है जिसे मैंने केवल डिबग करने के लिए समस्या को नोट करने के बाद बिन लॉग ऑन किया। धन्यवाद
अहमद कल्प Axan

धन्यवाद, इससे मदद मिलती है। मैं एक नहीं दिख रहा है BEGINया START TRANSACTION। क्या आप इसके बजाय, उपयोग कर रहे हैं autocommit=0? (मुझे पसंद है ... शुरू करें; यह लेनदेन की सीमा को स्पष्ट करता है।)
रिक जेम्स

इसलिए फ्रेमवर्क (स्प्रिंग) लेनदेन का प्रबंधन करता है और यह आमतौर पर ऑटोकॉमिट = 0 सेट करता है और अंत में होता है। मैं अनुमान लगा रहा हूं कि हम यहां ऑटोकॉमिट = 0 नहीं देख रहे हैं क्योंकि कनेक्शन पहले से ही उस स्थिति में था।
अहमद ऐसन एक्सन

जवाबों:


3

मैं दूसरे प्रश्न के बारे में एक परिकल्पना बनाने की कोशिश करता हूं:

यह देखते हुए कि कमिट से पहले होता है (कमेटी 14:16:06 पर है और सेलेक्ट 14:16:07 पर है) यह कैसे होता है कि सेलेक्शन ट्रांजेक्शन द्वारा डाली गई पंक्ति को वापस नहीं करता है?

लेनदेन वसंत द्वारा प्रबंधित किए जाते हैं। इसलिए यह संभव होगा कि selectवसंत को चलाने से पहले start transactionया इसने पहले ही किसी अन्य क्वेरी को चलाने के लिए कनेक्शन का उपयोग कर लिया हो।

मैं एक पहला सत्र शुरू करता हूँ जहाँ मैं एक तालिका में एक सम्मिलित अनुकरण करता हूँ 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)

मैं एक नया सत्र, सत्र 2 बनाता हूं, जहां autocommitइस नए सत्र में 0. सेट किया गया है, एक चयन करते समय एक लेनदेन निहित है।

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)

डालने के लिए session1 पर जाएँ।

session1> commit;

अब फिर से सेशन २ में जाएँ:

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

Session2 केवल सम्मिलित पंक्ति नहीं देख सकता है। यदि कोई commitसत्र 2 में उठाया गया है तो हम सत्र 1 में नई पंक्ति सम्मिलित कर सकते हैं

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

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

सामान्य लॉग ऐसा दिखता है:

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

पहली पंक्ति सत्र 2 से संबंधित है। यह तब होता है जब सत्र 2 लेनदेन को खोलता है।

मुझे नहीं पता कि क्या आपके मामले में ऐसा होता है। यदि अन्य प्रश्नों के लिए connection_id 36 का उपयोग किया गया था, तो आप अपने सामान्य लॉग में देख सकते हैं। आइये जानते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.