ธุรกรรม MySQL PHP ข้ามฐานข้อมูล

ฉันไม่พบคำตอบที่แน่ชัดว่าได้รับอนุญาตให้ทำธุรกรรมใน PHP ครอบคลุมหลายฐานข้อมูลหรือไม่

ฉันใช้วัตถุการเชื่อมต่อเดียวกัน (mysqli) และทำธุรกรรมในลักษณะนี้:

$mysqli->autocommit(false);

try {

    // Assume here that some code would throw an exception

    $stmt = $mysqli->prepare("INSERT INTO db1.x (column) VALUES (y)");
    $stmt->execute();
    $stmt->close();

    $stmt = $mysqli->prepare("INSERT INTO db2.x (column) VALUES (y)");
    $stmt->execute();
    $stmt->close();

    $mysqli->commit();
    // Great success

} catch (Exception $e) {

    $mysqli->rollback();
    throw $e; // handle elsewhere

}

สิ่งนี้ได้รับอนุญาตหรือไม่ และมันจะกระทำและย้อนกลับอย่างถูกต้องหรือไม่ ตามคู่มือ (http://dev.mysql.com/doc/refman/5.6/en/xa.html) และเธรดอื่นๆ บน SO ดูเหมือนว่าฉันจำเป็นต้องใช้คำสั่ง XA แต่ก็ไม่ชัดเจนจริงๆ (สำหรับฉัน) หากนี่คือเมื่อใช้เซิร์ฟเวอร์ฐานข้อมูลหลายตัว การเชื่อมต่อหลายรายการ หรือ โดยทั่วไปเมื่อรันโค้ดด้านบน


person nickdnk    schedule 24.02.2016    source แหล่งที่มา
comment
ฉันคิดว่าถ้าพวกเขาอยู่บนเครื่องโฮสต์ DB เดียวกันมันจะใช้งานได้   -  person Ray    schedule 25.02.2016
comment
ถ้าไม่ใช่ฉันก็ไม่สามารถใช้วัตถุ mysqli เดียวกันสำหรับทั้งสองคำสั่งได้   -  person nickdnk    schedule 25.02.2016
comment
ใช่ มันจะได้ผล ในกรณีนี้โดยเฉพาะ การทำธุรกรรมเสร็จสิ้นต่อการเชื่อมต่อ หากคุณเปิดการเชื่อมต่อสองรายการไว้ และเริ่มธุรกรรมในแต่ละธุรกรรม คุณจะมีธุรกรรมสองรายการแยกกัน/ต่างกันโดยสิ้นเชิง และการดำเนินการในธุรกรรมหนึ่งจะไม่ส่งผลกระทบต่ออีกธุรกรรม   -  person Marc B    schedule 25.02.2016
comment
@MarcB - ฉันรู้แล้วและนั่นเป็นสาเหตุที่คำถามระบุโดยเฉพาะว่าฉันใช้วัตถุการเชื่อมต่อเดียวกัน หากคุณแน่ใจและสามารถสนับสนุนการเรียกร้องของคุณได้โปรดโพสต์คำตอบ :)   -  person nickdnk    schedule 25.02.2016
comment
ดูเหมือนว่าตัวอย่างนี้มีเกือบทุกอย่างที่คุณต้องการในการตรวจสอบอยู่แล้ว   -  person Don't Panic    schedule 25.02.2016
comment
@ Don'tPanic ฮ่าฮ่า - ใช่ แต่ฉันไม่แน่ใจ 100% ว่าดูเหมือนว่าจะได้ผลเสมอเท่ากับคุณควรทำเช่นนี้และนั่นคือวิธีที่มันควรจะทำ :)   -  person nickdnk    schedule 25.02.2016


คำตอบ (2)


ตามคำขอความคิดเห็นด้านบน ละเว้นการสร้าง/ใช้ความคิดเห็น:

mysql> create database x;
mysql> use x;
mysql> create table x (x int);
mysql> create database y;
mysql> use y;
mysql> create table y (y int);
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into x.x values (1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into y.y values (1);
Query OK, 1 row affected (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from x.x;
Empty set (0.00 sec)

mysql> select * from y.y;
Empty set (0.00 sec)

โปรดทราบว่าทั้งหมดนี้อยู่ในการเชื่อมต่อเดียวไปยังอินสแตนซ์ mysql เดียว มันจะไม่ทำงานหาก dbs โฮสต์อยู่บนเซิร์ฟเวอร์ที่แตกต่างกัน หรือคุณกำลังสร้าง/แทรกแต่ละรายการในการเชื่อมต่อที่ต่างกัน

person Marc B    schedule 24.02.2016
comment
ฉันคิดว่าฉันจะใช้คำพูดของคุณและตัวอย่างนี้ ขอบคุณ :) - person nickdnk; 25.02.2016

ธุรกรรมมีผลกับเซิร์ฟเวอร์โดยรวม ฐานข้อมูลใช้สำหรับการจัดกลุ่มตารางโดยมีวัตถุประสงค์ในการให้สิทธิ์ (เช่น คุณสามารถให้สิทธิ์แก่ database.*) และระบุค่าเริ่มต้นบางอย่างเมื่อสร้างตารางใหม่ และใช้เพื่ออนุญาตให้คุณเลือกฐานข้อมูลเริ่มต้นด้วยคำสั่ง USE ดังนั้นคุณจึงไม่จำเป็นต้องระบุชื่อฐานข้อมูลในทุก ๆ แบบสอบถาม

person Barmar    schedule 24.02.2016