INSERT ได้รับการกำหนดอัตโนมัติหรือไม่


13

แอปพลิเคชันของเรายิงแบบสอบถาม INSERT ไปยังฐานข้อมูล MySQL เพื่อเพิ่มบันทึก ฉันต้องการทราบว่าบันทึกได้รับการกำหนดอัตโนมัติหรือไม่ ถ้าฉันรันคำสั่ง ROLLBACK ฐานข้อมูลจะทำการย้อนกลับเมื่อใด การย้อนกลับเป็นไปได้หลังจากคอมมิชชันหรือไม่?


เพื่อความกระจ่างแจ้งฉันติดแท็กเป็น 'innodb' 19 ชั่วโมงที่ผ่านมาเนื่องจาก InnoDB ใช้ COMMIT / ROLLBACK
RolandoMySQLDBA

สิ่งนี้จะได้รับ +1 สำหรับเตือนผู้พัฒนาและ DBA เพื่อให้ความสนใจกับพฤติกรรมการทำธุรกรรมกระบวนทัศน์ของแอพพลิเคชั่นที่สนับสนุนการทำธุรกรรมและผลที่ตามมา (ดีหรือไม่ดี)
RolandoMySQLDBA

ฉันตอบคำถามของคุณด้วยความคิดเห็นภายใต้คำตอบของฉัน
RolandoMySQLDBA

คำตอบ:


10

คำตอบสำหรับคำถามของคุณขึ้นอยู่กับว่าคุณอยู่ในธุรกรรมที่จะขยายงบมากกว่าหนึ่งรายการหรือไม่ (คุณติดแท็กคำถามกับ InnoDB คำตอบจะแตกต่างจาก MyISAM)

จากคู่มืออ้างอิง: http://dev.mysql.com/doc/refman/5.1/en/commit.html

โดยค่าเริ่มต้น MySQL จะทำงานโดยเปิดใช้งานโหมดปรับแต่งอัตโนมัติ ซึ่งหมายความว่าทันทีที่คุณดำเนินการคำสั่งที่อัปเดต (แก้ไข) ตาราง MySQL จะจัดเก็บการอัปเดตบนดิสก์เพื่อให้ถาวร

ใช่โดยค่าเริ่มต้นหากคุณเพิ่งใช้INSERTงานระเบียนที่คุณแทรกจะถูกกำหนดและไม่มีจุดใดที่พยายามย้อนกลับ (สิ่งนี้มีประสิทธิภาพเหมือนกับการตัดคำสั่งแต่ละรายการระหว่างBEGINและCOMMIT.)

แต่ถ้าคุณจัดการกับการทำธุรกรรมอย่างชัดเจนคุณจะต้องใช้COMMITเพื่อกระทำการจัดเก็บระเบียน ROLLBACKแต่คุณยังจะสามารถที่จะใช้งาน

คุณสามารถเริ่มทำธุรกรรมอย่างชัดเจนโดยใช้START TRANSACTION(หรือBEGIN) นี่เป็นอิสระจากการautocommitตั้งค่า (โดยค่าเริ่มต้น):

ด้วยการทำธุรกรรมเริ่มต้นการเติมข้อความอัตโนมัติจะยังคงปิดใช้งานจนกว่าคุณจะสิ้นสุดธุรกรรมด้วย COMMIT หรือ ROLLBACK โหมด autocommit จะเปลี่ยนกลับไปเป็นสถานะก่อนหน้า

อีกวิธีหนึ่งถ้าautocommit=0ฉันคิดว่าคำสั่งใด ๆ ที่ตามหลังการสิ้นสุดธุรกรรมอื่นจะเริ่มต้นธุรกรรม (แต่คุณยังสามารถใช้START TRANSACTIONอย่างชัดเจน) อย่างน้อยฉันก็ตีความสิ่งนี้ :

โหมด autocommit หากตั้งค่าเป็น 1 การเปลี่ยนแปลงทั้งหมดในตารางจะมีผลทันที หากตั้งค่าเป็น 0 คุณต้องใช้ COMMIT เพื่อยอมรับการทำธุรกรรมหรือย้อนกลับเพื่อยกเลิก ถ้า autocommit เป็น 0 และคุณเปลี่ยนเป็น 1, MySQL จะทำการคอมมิทอัตโนมัติของธุรกรรมใด ๆ ที่เปิดอยู่ อีกวิธีหนึ่งในการเริ่มต้นธุรกรรมคือการใช้คำสั่ง START TRANSACTION หรือ BEGIN ดูหัวข้อ 12.3.1“ การทำธุรกรรมเริ่มต้นคอมมิทและย้อนกลับไวยากรณ์”

โดยเฉพาะอย่างยิ่ง "อีกวิธีหนึ่งในการเริ่มต้นธุรกรรม" ดูเหมือนจะบอกเป็นนัยว่าการตั้งค่า "autocommit = 0" นั้นเพียงพอที่จะเริ่มทำธุรกรรม (อย่างน้อยก็ต่อหน้าแต่ละคำสั่งที่เริ่มเซสชันหรือตามด้วยCOMMIT/ ROLLBACK) ฉันอยากจะแนะนำให้ใช้BEGINหรือSTART TRANSACTIONอย่างชัดเจนแม้ว่าautocommit=0มันจะทำให้มันชัดเจนยิ่งขึ้นเมื่อเห็นว่าการทำธุรกรรมเริ่มต้นหรือสิ้นสุด

(วิธีที่คุณเริ่มทำธุรกรรมอาจขึ้นอยู่กับวิธีที่แอปพลิเคชันของคุณใช้ MySQL)


1
สมควรได้รับ +1 เพื่อกำหนดโปรโตคอลธุรกรรมอย่างสมบูรณ์
RolandoMySQLDBA

@Bruno สำหรับ MyISAM ที่ "กระทำ" และ "ย้อนกลับ" ไม่ทำงานเม็ดมีดจะไม่ได้ครึ่ง
Pacerier

7

โดยค่าเริ่มต้นInnoDB เป็นชุดที่จะ autocommit = 1 หรือบน เมื่อความมุ่งมั่นที่พวกเขาไม่สามารถย้อนกลับ

คุณจะต้องทำหนึ่งในสองสิ่งนี้เพื่อปิดการใช้งานมันไปข้างหน้า

ตัวเลือก 1: เพิ่มส่วนนี้ลงใน /etc/my.cnf แล้วรีสตาร์ท mysql

[mysqld]
autocommit=0

ตัวเลือก 2: ดำเนินการหนึ่งในสิ่งเหล่านี้ในการเปิด DB Conenction ก่อนเริ่มต้น SQL ที่มีความหมายใด ๆ

SET autocommit = 0;
START TRANSACTION;

ภายใต้สองตัวเลือกนี้คุณจะต้องดำเนินการด้วยตนเอง COMMIT หรือ ROLLBACKด้วยตนเอง

ข้อแม้

หากตารางคือ MyISAM คำอธิบายนั้นง่ายกว่า เนื่องจากไม่มีธุรกรรมสำหรับเอนจินการจัดเก็บ MyISAM INSERTs, UPDATE และ DELETE ทั้งหมดที่ดำเนินการจึงเป็นแบบถาวร ไม่มีการย้อนกลับใด ๆ


เพื่อความกระจ่างเพิ่มเติมคำตอบของฉันพูดถึงทั้งเครื่องมือเก็บข้อมูล InnoDB และ MyISAM
RolandoMySQLDBA

1
ในกรณีที่ Auto Commit ปิดอยู่ใน InnoDB และแอปพลิเคชันของฉันทำการแทรกการสืบค้นและฉันลืมที่จะใช้งาน Commit การเปลี่ยนแปลงจะหายไปในไม่ช้า
RPK

หากใบสมัครของคุณยิงคอมมิทด้วยตนเองหลังจากแต่ละ INSERT มันจะถูกเขียนและไม่สามารถลบได้ หากการเชื่อมต่อฐานข้อมูลตายก่อนที่คุณจะยอมรับการเปลี่ยนแปลงทั้งหมดจะสูญหายไปและการย้อนกลับเกิดขึ้น หากคุณดำเนินการ DDL (สร้างตาราง, ตาราง DROP, แก้ไขตาราง ฯลฯ ) หรือออกด้วยตนเองล็อคตาราง INSERTs จะถูก autocommited หากคุณใช้การทำธุรกรรมเริ่มต้นการเปลี่ยนแปลงที่ไม่ได้รับการยอมรับทั้งหมดจะถูกส่งไป
RolandoMySQLDBA

1
เกี่ยวกับ "หากคุณใช้การทำธุรกรรมเริ่มต้นการเปลี่ยนแปลงที่ไม่ได้กระทำทั้งหมดจะถูกส่งไป" (ในบริบทของ DDLs มิฉะนั้นจะย้อนกลับ) นอกจากนี้ยังมีการกระทำโดยปริยายมาก่อน (การกระทำโดยนัยหลังจากนั้นมาจากรุ่น 5.5.3 ตามเอกสารประกอบ)
บรูโน่

1
"หากคุณใช้การทำธุรกรรมเริ่มต้นการเปลี่ยนแปลงที่ไม่ได้รับการยอมรับทั้งหมดจะถูกส่งไป" - ฉันได้รับแนวคิดจาก MySQL 5.0 คู่มือการศึกษาเพื่อการรับรอง (ไอ 0-672-32812-7) หน้า 418 ซึ่งตั้งชื่อรายการเริ่มต้นตั้งค่า AUTOCOMMIT = 1 ตารางแท็บเล็ตปลดล็อกแท็บตารางตัดทอนตารางชื่อ DROP DATABASE สร้าง INDEX, BEGIN และ ALTER TABLE ภายใต้หัวเรื่อง "ภายใต้บางสถานการณ์ธุรกรรมปัจจุบันอาจสิ้นสุดโดยปริยาย: หากคุณออกข้อความใด ๆ ต่อไปนี้ InnoDB จะทำหน้าที่ส่งคำสั่งที่ไม่มีข้อผูกมัดก่อนหน้าของธุรกรรมปัจจุบัน ธุรกรรมใหม่ "
RolandoMySQLDBA
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.