เมื่อเร็ว ๆ นี้ฉันเรียนรู้ที่จะทดสอบ mybatis และไม่มีปัญหาในการเพิ่มลบการแก้ไขและตรวจสอบเพียงอย่างเดียว ในที่สุดฉันพบปัญหาหลายอย่างเมื่อใช้การทดสอบ MVN:
1. การอัปเดตล้มเหลวเนื่องจากฐานข้อมูลหยุดชะงัก
2. เลือกรอเพราะพูลการเชื่อมต่อการเชื่อมต่อจะหมดและต้องรอ
รับ:
1. กล้าหาญในการสำรวจและความเพียรเป็นชัยชนะ เมื่อฉันเห็นข้อผิดพลาดครั้งแรกฉันสับสนเพราะฉันไม่เห็นข้อผิดพลาดเลย มันเป็นข้อผิดพลาดที่รายงานภายในกรอบ ฉันลังเลว่าจะนอนโดยตรง
ฉันรู้สึกว่ามันเกือบ 12 นาฬิกา ในที่สุดฉันก็พบปัญหาเล็กน้อย
2. เหมือนกับข้างบนคุณต้องกล้าขุดลงไปในรหัสที่คุณไม่เข้าใจและกล้าที่จะศึกษารหัสที่คุณไม่เข้าใจ
3. การอยู่ไกลออกไปและไกลออกไปจาก coder ที่ผ่านการรับรองเพราะยิ่งคุณเรียนรู้มากเท่าไหร่คุณก็ยิ่งรู้สึกถึงช่องโหว่และรหัสของคุณก็เต็มไปด้วยข้อผิดพลาด ดังนั้นอย่าลืมบันทึกไว้
บันทึกต่อไปนี้ของปัญหาทั้งสองนี้
1. Deadlock ฐานข้อมูล MySQL
ที่นี่ขอบคุณ http://www.cnblogs.com/lin-xuan/p/5280614.html ฉันพบคำตอบ ที่นี่ฉันจะสร้างมันขึ้นมาใหม่:
ฐานข้อมูล Deadlock เป็นปัญหาที่พบบ่อยโดยฐานข้อมูลธุรกรรม (เช่น SQL Server, MySQL ฯลฯ ) เว้นแต่ปัญหาการหยุดชะงักของฐานข้อมูลจะเกิดขึ้นบ่อยครั้งและผู้ใช้ไม่สามารถทำงานได้ปัญหาการหยุดชะงักของฐานข้อมูลโดยทั่วไปจะไม่ร้ายแรง เพียงแค่ลองจับในแอปพลิเคชัน ดังนั้นการหยุดชะงักของข้อมูลจะเกิดขึ้นได้อย่างไร?
InnoDB ใช้ล็อคระดับแถวซึ่งแบ่งออกเป็นล็อคที่ใช้ร่วมกันและล็อค mutex (x)
•การล็อคที่ใช้ร่วมกันใช้สำหรับบรรทัดการอ่านธุรกรรม
• Mutex ใช้สำหรับการอัปเดตธุรกรรมหรือลบหนึ่งบรรทัด
เมื่อไคลเอนต์ A ถือล็อคที่ใช้ร่วมกันและร้องขอ mutex x; ในเวลาเดียวกันไคลเอนต์ B ถือ Mutex X และขอล็อค S. ที่ใช้ร่วมกันในสถานการณ์ข้างต้นการหยุดชะงักของฐานข้อมูลจะเกิดขึ้น หากไม่ชัดเจนพอโปรดดูตัวอย่างด้านล่าง
เปิดลูกค้าสองคนสองลูกค้า MySQL
ลูกค้า A:
เปิดธุรกรรมและล็อคล็อคที่ใช้ร่วมกันเมื่อ id = 12:
mysql> เริ่มธุรกรรม; แบบสอบถามตกลง, 0 แถวที่ได้รับผลกระทบ (0.00 วินาที) mysql> เลือก * จากบล็อกที่ id = 12 ล็อคในโหมดแชร์;+----+-------+-----------+| id | ชื่อ | Author_id |+----+-------+-----------+| 12 | Testa | 50 |+----+-------+-----------+1 แถวในชุด (0.00 วินาที)
ลูกค้า B:
เริ่มการทำธุรกรรมและพยายามลบ ID = 12:
mysql> เริ่มธุรกรรม; แบบสอบถามตกลง, 0 แถวที่ได้รับผลกระทบ (0.00 วินาที) mysql> ลบออกจากบล็อกโดยที่ id = 12;
การดำเนินการลบต้องใช้ mutex (x) แต่ mutex x และล็อคที่ใช้ร่วมกันไม่เข้ากัน ดังนั้นธุรกรรมการลบจะถูกวางไว้ในคิวคำขอล็อคและไคลเอนต์ B ถูกบล็อก
ในเวลานี้ลูกค้า A ยังต้องการลบ 12:
mysql> ลบออกจากบล็อกโดยที่ id = 12; แบบสอบถามตกลง 1 แถวได้รับผลกระทบ (0.00 วินาที)
ซึ่งแตกต่างจากบทความอ้างอิงการลบนั้นประสบความสำเร็จ แต่ลูกค้า B มีข้อผิดพลาด:
ข้อผิดพลาด 1213 (40001): พบว่าหยุดชะงักเมื่อพยายามล็อค ลองรีสตาร์ทธุรกรรม
ดังนั้นฉันพยายามลบ 13 และทุกอย่างถูกบล็อก:
ในรหัสทดสอบ mybatis ของฉันเนื่องจากการทดสอบก่อนหน้านี้ไม่ได้กระทำมันทำให้เกิดการหยุดชะงักและมันก็โอเคหลังจากกระทำ ที่นี่ฉันอยากจะบอกว่าฐานข้อมูลได้ถูกส่งกลับไปยังครูและต้องมีการตรวจสอบล็อคและธุรกรรมอีกครั้ง
2. จำนวนการเชื่อมต่อฐานข้อมูลไปยังแหล่งข้อมูลใน myBatis
เมื่อฉันทดสอบ MVN ฉันพบบันทึกการพิมพ์แบบสอบถาม:
2016-07-21 23: 43: 53,356 debug [org.apache.ibatis.transaction.jdbc.jdbctransaction]-เปิดการเชื่อมต่อ JDBC
2016-07-21 23: 43: 53,356 debug [org.apache.ibatis.datasource.pooled.pooledDataSource]-รอนานถึง 20000 ล้านวินาทีสำหรับการเชื่อมต่อ
ดังนั้นหลังจากรอสักครู่การประหารชีวิตก็ประสบความสำเร็จ ติดตามซอร์สโค้ดและค้นหาบันทึกนี้เพื่อทำความเข้าใจ ก่อนอื่นการกำหนดค่าการเชื่อมต่อฐานข้อมูลที่ฉันใช้ที่นี่คือ mybatis ค่าเริ่มต้น:
<environment id = "การพัฒนา"> <transactionManager type = "jdbc"/> <dataSource type = "pooled"> <property name = "driver" value = "$ {jdbc.driver}"/> <property name = "url" value = "$ {jdbc.url}"/> value = "$ {jdbc.password}"/> <property name = "รหัสผ่าน" value = "$ {jdbc.password}"/> <dataSource> </environment> หลังจากจำนวนการเชื่อมต่อในพูลเชื่อมต่อฐานข้อมูลคุณต้องรอ 2 วินาทีก่อนที่จะได้รับ {// พูลมีการเชื่อมต่อที่มีอยู่ = state.idleconnections.remove (0); ถ้า (log.isdebugenabled ()) {log.debug ("ตรวจสอบการเชื่อมต่อ" + conn.getRealHashCode () + "จากพูล");}} อื่น ๆ poolmaximumactiveConnections) {// สามารถสร้างการเชื่อมต่อใหม่ = ใหม่ pooledConnection (dataSource.getConnection (), นี่); ถ้า (log.isdebugenabled ()) {log.debug ("การเชื่อมต่อที่สร้างขึ้น" state.activeConnections.get (0); LongestCheckOuttime = oldestactiveConnection.getCheckOutTime (); ถ้า (LongestCheckOutTime> PoolMaximumCheckOutTime) {// สามารถเรียกร้องการเชื่อมต่อ overdue การเชื่อมต่อที่เกินกำหนด LongestCheckOuttime; state.activeConnections.remove (oldestactiveConnection); ถ้า (! oldestactiveConnection.getRealConnection (). getautocommit ()) {ลอง {oldestactiveConnection.getRealConnection () back ");}} conn = new PooledConnection (oldestactiveConnection.getRealConnection (), นี่); oldestactiveConnection.invalidate (); ถ้า (log.isdebugenabled () {log.debug ( (! countedWait) {state.hadtowaitCount ++; countedWait = true;} ถ้า (log.isdebugenabled ()) {log.debug ("รอตราบเท่าที่" + pooltimetowait + "หลายล้านสำหรับการเชื่อมต่อ"); System.currentTimeMillis (); state.wait (pooltimetowait); state.accumulatedwaittime += system.currentTimeMillis () - wt;} catch (interruptedException e) {break;}}}}}}} ถ้า (conn! = null) (! conn.getRealConnection (). getAutocommit ()) {conn.getRealConnection (). การย้อนกลับ ();} conn.setConnectionTypecode (AssembleConnectionTypecode (dataSource.getUrl () ชื่อผู้ใช้ รหัสผ่าน)); conn.setcheckouttimestamp (System.currentTimeMillis ()); conn.setLastusedTimestamp (System.currentTimeMillis ()); state.activeConnections.add (conn); state.requestcount ++; (log.isdebugenabled ()) {log.debug ("การเชื่อมต่อที่ไม่ดี ("+conn.getRealHashCode ()+") ถูกส่งกลับจากสระว่ายน้ำรับการเชื่อมต่ออื่น"); state.badConnectionCount ++; localBadConnectionCount ++; conn = null; (log.isdebugenabled ()) {log.debug ("pooledDataSource: ไม่สามารถเชื่อมต่อที่ดีกับฐานข้อมูล");}}}}}}}}เมื่อจำนวนการเชื่อมต่อน้อยกว่า 10 มันจะรอการเชื่อมต่อมากกว่า 10 ครั้งมิฉะนั้นจะมีการรายงานข้อผิดพลาด
ข้างต้นคือฐานข้อมูลการอัปเดต MyBatis เพื่อรับการรอการเชื่อมต่อฐานข้อมูล ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!