บริบท: เฟรมเวิร์กที่ใช้คือ Spring และเคียวรีทั้งหมดรันด้วย JdbcTemplate เซิร์ฟเวอร์ Mysql คือ 5.6.19 table
เป็นInnoDB table
และค่าเริ่มต้นเหมือนauto commit
และระดับการแยกทำซ้ำอ่านเป็นชุด
ปัญหา : Insert
เกิดขึ้นภายในธุรกรรมและselect
ที่อ่านข้อมูลเดียวกันที่แทรกไว้ไม่เห็นข้อมูล select
วิ่งหลังจากinsert
และหลังการทำธุรกรรมมีinsert
commited
ฉันได้เปิดใช้งาน bin log รวมถึง log ทั่วไปใน 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) ไม่ควรเป็นส่วนหนึ่งของการทำธุรกรรมทั้งหมด เป็นการเรียก API ที่แยกต่างหากและไม่เกี่ยวข้องอย่างสมบูรณ์ อาจเป็นการผสมกับธุรกรรมหรือฉันกำลังอ่านบันทึกที่ไม่ถูกต้อง AFAIK เนื่องจากมีอยู่ในเธรดเดียวกันซึ่งแสดงถึงการแทรกอยู่ในธุรกรรม
สองรายการถัดไปinserts
เป็นส่วนหนึ่งของธุรกรรมและดูเหมือนว่าจะกระทำ (249936514) ตอนนี้แบบสอบถามแบบใช้เลือกข้อมูล (แบบสอบถามสุดท้ายในบันทึกทั่วไป) จะทำงานหลังจากการส่งข้อมูลและจะไม่เห็นข้อมูล ส่งคืน 0 แถว สิ่งนี้จะเกิดขึ้นเมื่อพิจารณาจากข้อมูลได้committed
อย่างไร หรือcommit
ไม่อยู่ในเธรด 40? เนื่องจากมันไม่มี id ของเธรด
เพื่อสรุปฉันมีสองคำถาม
การทำงาน
BEGIN
ใน binlog อยู่ก่อนหน้านี้INSERT INTO user_geo_loc
(ซึ่งไม่ได้เป็นส่วนหนึ่งของการทำธุรกรรม) หรือไม่นี่เป็นข้อผิดพลาดของ spring / Jdbc หรือ MySql เพียงแค่ทำสิ่งนี้เพราะรู้ว่าธุรกรรมนี้ได้ทำไปแล้ว (เนื่องจากธุรกรรมถูกเขียนลงใน binlog สำเร็จแล้ว) ดังนั้นจะไม่มีการย้อนกลับการให้คอมมิชชันเกิดขึ้นก่อนการเลือก (commit อยู่ที่ 14:16:06 และ select เป็นเวลา 14:16:07) การเลือกไม่ส่งคืนแถวที่แทรกโดยธุรกรรม?
นี่มันน่างงมาก ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม
หมายเหตุ: แบบสอบถามทั้งในถังขยะและบันทึกแบบสอบถามได้รับการแก้ไขเพื่อลบข้อมูลที่ละเอียดอ่อน แต่สาระสำคัญของการสืบค้นยังคงเหมือนเดิม
แก้ไข: อัปเดตด้วยบันทึกทั่วไปและบันทึกแบบสอบถามพร้อมด้วยตัวอย่างโดยละเอียด
BEGIN
START TRANSACTION
คุณใช้แทนautocommit=0
ไหม (ฉันชอบเริ่มต้น ... กระทำมันทำให้ขอบเขตของการทำธุรกรรมชัดเจน)