2012-03-15 57 views
1

我有兩個表作爲作者和書。我想從作者表插入數據到書桌。 如果插入成功,則作者表的數據將被刪除,如果不成功,則不會從作者表中刪除數據。 我想使用Rollback,但這裏的作者和圖書是兩個不同的數據庫在不同的服務器。 任何建築功能都存在於php和mysql中,我可以做到這一點。php-mysql回滾替代函數

+0

這兩個數據庫都是InnoDB嗎? – biziclop 2012-03-15 12:22:34

+0

到目前爲止你寫了什麼代碼?顯示代碼,以便我們可以幫助您。 – 2012-03-15 12:22:39

+0

yes.two數據庫都是InnoDB – salma 2012-03-15 12:26:14

回答

0

先插入從作者表中的所有行預訂表

insert into database1.book (fields_BookTable) 
    select fields_aAuthor_inBookTable from database2.author 

然後檢查使用id字段數據是否已經被插入到書表

delete from database2.author where id in (select id from database1.book); 
0

交易是一個「數據庫」內隔離。

你應該真正做的是使用單個數據庫連接來使用這兩個數據庫。

在MySQL中,「數據庫」實際上更像是其他服務器中的「目錄」或「模式」。您可以在權限允許的同一連接中使用來自其他數據庫的表。

對於通過PHP(未經測試)管理事務:

$objConnect = mysql_connect("localhost","root","root") or die(mysql_error()); 
$objDB = mysql_select_db("mydatabase"); 

//*** Start Transaction ***// 
mysql_query("BEGIN"); 

$query = "query1 comes here...";  

if(mysql_query($query)) { 
    // Commit Transaction 
    mysql_query("COMMIT"); 
    echo "Save Done."; 
} 
else { 
    // RollBack Transaction 
    mysql_query("ROLLBACK"); 
    echo "Error Save [".$strSQL."]"; 
} 
mysql_close($objConnect); 

而且檢查:http://dev.mysql.com/doc/refman/5.0/en/commit.html

+0

在這裏,數據庫存在兩個不同的服務器 – salma 2012-03-18 05:20:40

0

由PHP控制的解決方案,假設mysql擴展和數字鍵列(NB你會如果你絕對不能在交易中包裝它,例如如果有兩個不同的服務器,則只做這個):

// Server connections 
$srcConn = mysql_connect('somewhere', 'user', 'pass'); 
$dstConn = mysql_connect('elsewhere', 'user', 'pass'); 

// Fetch data to move into an array 
$query = " 
    SELECT * 
    FROM `srcdb`.`table` 
"; 
$result = mysql_query($query, $srcConn); 
$data = array(); 
while ($row = mysql_fetch_assoc($result)) $data[] = $row; 
mysql_free_result($result); 

// Rows to handle per cycle 
// A larger number reduces the number queries, but you need to respect the MySQL 
// max_allowed_packet and it will also increase PHP memory usage 
$rowsPerCycle = 100; 

// Name of the primary key column 
$pKName = 'id'; 

// This will hold the column names in the right order, without the PK 
// You could make the list static if you know what it will be 
// You may also need to keep the PK value 
$colNames = array(); 
foreach ($data[0] as $colName => $val) { 
    if ($colName != $pKName) { // Remove me if you need to keep the PK values 
    $colNames[] = $colName; 
    } 
} 

// Keep looping while $data still has some elements 
while ($data) { 

    // Remove $rowsPerCycle elements from the beginning of $data 
    $cycleData = array_splice($data, 0, $rowsPerCycle); 

    // This array holds a list of the primary keys we are migrating 
    $cycleIds = array(); 

    // Build the base query 
    $query = " 
    INSERT INTO `destdb`.`table` 
     (`".implode("`, `", $colNames)."`) 
    VALUES 
    "; 

    // Loop the rows and append them to the query (after escaping them, of course...) 
    foreach ($cycleData as $row) { 
    $cycleIds[] = $row[$pKName]; 
    unset($row[$pKName]); // Remove me if you need to keep the PK values 
    $query .= "\n('" . implode("', '", array_map('mysql_real_escape_string', $row, array_fill(0, count($row), $dstConn)) . "'),"; 
    } 

    // Do the insert 
    if (!mysql_query($query, $dstConn)) { 
    // Handle insert errors here 
    trigger_error('MySQL Error: '.mysql_error($dstConn).'; Query: '.$query); 
    } 

    // Do the delete 
    $query = " 
    DELETE FROM `srcdb`.`table` 
    WHERE `$pKName` IN (".implode(', ', $cycleIds).") 
    "; 
    if (!mysql_query($query, $srcConn)) { 
    // Handle insert errors here 
    trigger_error('MySQL Error: '.mysql_error($srcConn).'; Query: '.$query); 
    } 

}