2010-02-10 50 views
0

我有一个用户注册procdedure,这个步骤:Mysql的事务处理

如果用户发送registraion形式则:

1. step: run a QUERY 
2. step: run another QUERY 
3. make a directory1 on the server 
4. make a sub directory2 into the directory1 
5. make another sub directory3 into the directory1 
6. upload an image into the sub directory2 

所以这是很好地工作。但是如果在这个程序运行的时候发生了什么,我很害怕,所以如果程序在第4步中断,那么我的表中有一些不必要的行,因为第1步。 2.

所以我想我必须使用mysql事务句柄,但我不知道如何。我觉得somethink这样的:

 START TRANSACTION (what is the exact format?) 
    1. step: run a QUERY 
    2. step: run another QUERY 
    3. make a directory1 on the server 
    4. make a sub directory2 into the directory1 
    5. make another sub directory3 into the directory1 
    6. upload an image into the sub directory2 
    COMMIT (if all step ok. but how can i check this?) 
    ROLLBACK (if something wrong; but how can i check this?) 

I this transaction handle not handle the FILE transactions, so i ROLLBACK function is called, then i have to delete manually the directorys if created already?! 

Sorry, two more question: 
  • 如果程序中断,例如在步骤2中,和ROLLBACK被调用,那么sciprt将停止或从月底开始?或者我需要编写一个回调功能可按这样的事情:(这是我怎样做?)

    function begin() { @mysql_query("BEGIN");} 
    function commit(){ @mysql_query("COMMIT");} 
    function rollback() 
    { 
        @mysql_query("ROLLBACK"); 
        echo "oops"; 
        exit(); 
    } 
    $inster_query="insert into.... 
    begin(); 
    $result_insert = @mysql_query($inster_query); 
    if(!$result_insert) 
    { 
        rollback(); 
    } 
    $update_query="update.... 
    $result_up = @mysql_query($update_query); 
    if(!$result_up) 
    { 
        rollback(); 
    } 
    . 
    . 
    commit(); 
    
  • 如何测试这一点,如果它的工作或没有? 谢谢。

回答

1

START TRANSACTION - 见手册

  1. 步骤:运行查询。如果失败 - 回滚。
  2. 步骤:运行另一个QUERY。如果失败 - 回滚。
  3. 在服务器上建立一个目录1。如果失败 - 回滚。
  4. 使子目录2进入directory1。如果失败,请删除directory1并回滚。
  5. 使另一个子目录3进入directory1。如果失败,请删除子目录2和目录1并回滚。
  6. 将图像上传到子目录2中。如果失败,请删除三个先前的目录并回滚。 COMMIT

从开发的角度来看,您需要创建Undo堆栈并将那些能够撤消工作的对象推送到那里。如果出现故障,您需要 - >执行()整个撤消堆栈。我想你知道如何检查目录创建/文件上传失败?

+0

好的,所以我需要逐步检查它只是最后;这个撤销堆栈认为..我不知道我明白,但我尝试按你的建议做; – Holian 2010-02-10 09:46:13

+0

是的,一步一步检查。关于撤消/重做堆栈的东西:http://bytes.com/topic/c-sharp/answers/235457-how-do-we-normally-implement-undo-redofunction – 2010-02-10 09:51:19

+0

我编辑我的评论,增加两个问题。如果你有一点时间请看 – Holian 2010-02-10 10:00:01

1

,你想要做的步骤是:

1. step: run a QUERY 
2. step: run another QUERY 
3. make a directory1 on the server 
4. make a sub directory2 into the directory1 
5. make another sub directory3 into the directory1 
6. upload an image into the sub directory2 

在这里首先我要对查询洽谈...含义如何,您可以发送多个查询,万事如意之后拯救他们...
假设你的数据库名称为'database',表名是'table_1''table_2''table_3' ... ,你想要做的事象下面这样:

step 1: insert a row in table_1 
step 2: update a column in table_2 where id is 1 
step 3: insert another row in table_3 

,但你需要完成所有这三个步骤或没有他们... 在这种情况下,您可以使用此PHP代码...

// first connect and select to your mysql database... 
// before sending any queries (INSERT, UPDATE etc.) we have send this command else it will not work... 
mysql_query("START TRANSACTION;"); 
/* this command will say to the mysql that it only have to calculate the queries that we are 
sending is right or have problems... if everything is right, it will remember the query and 
after sending the confirmation it will trigger the queries... besides if the query has any 
problem then it will return FALSE only... moreover for right query mysql return TRUE...*/ 
// now I will send the queries and save the return values to different variables... 
$query1 = "INSERT INTO `database`.`table_1` (col1, col2) VALUES ('value1', 'value2');"; 
$query1 = mysql_query($query1); 
$query2 = "UPDATE `database`.`table_2` SET col1='value1', col1='value1' WHERE id='1';"; 
$query2 = mysql_query($query2); 
$query3 = "INSERT INTO `database`.`table_3` (col1, col2) VALUES ('value1', 'value2');"; 
$query3 = mysql_query($query3); 
// now if anything is wrong, I will get FALSE as return value for each wrong query... 
// if all of them are TRUE, we will send the confirmation for save them... 
// else we will say to forget whatever we send before... 
if($query1 && $query2 && $query3){ 
    // send confirmation 
    mysql_query('COMMIT;'); 
    /* NOTE: after you send COMMIT you can't ROLLBACK any query or data...*/ 
} else { 
    // order to forget whatever we send before 
    mysql_query('ROLLBACK'); 
    /* NOTE: after you send ROLLBACK you will lose all the queries that you send 
    after you send START TRANSACTION to mysql...*/ 
} 

注意:始终保持在你的心中,你不能ROLLBACK所有mysql_query ...这是你不能ROLLBACK ......

CREATE DATABASE 
ALTER DATABASE 
DROP DATABASE 
CREATE TABLE 
ALTER TABLE 
DROP TABLE 
RENAME TABLE 
TRUNCATE TABLE 
CREATE INDEX 
DROP INDEX 
CREATE EVENT 
DROP EVENT 
CREATE FUNCTION 
DROP FUNCTION 
CREATE PROCEDURE 
DROP PROCEDURE 

我想你的列表得到你想要做的答案...但是这里是你的项目的php代码...

// connect and select your database... 
mysql_query("START TRANSACTION;"); 
/* step 1 */ 
$query1 = "your query"; 
$query1 = mysql_query($query1); 
/* step 2 */ 
/* you can also use multiple line to build your query */ 
$query2 = "your query part 1"; 
$query2 .= "your query part 2"; 
$query2 .= "your query part 3"; 
$query2 = mysql_query($query2); 
/* step 3 */ 
mkdir(' the path you want to create ', 0700); 
/* here '0700' is the mode (permission or chmod)... 
if you don't know about it or want to know about it check the link... 
www.php.net/manual/en/function.chmod.php */ 
/* step 4 */ 
mkdir('<the path you write in step 3>/<the folder name that you want to create in step 4>', 0700); 
/* step 5 */ 
mkdir('<the path you write in step 3>/<the folder name that you want to create in step 5>', 0700); 
/* step 6 */ 
/* I am really sorry to say that I have on knowledge about 
the code that need to write for uploading a image or any file... 
so I am unable to help you for this step */ 
/* now we need to check is everything is right or not... 
we will create a variable '$rollback' and 
set its value as FALSE... if we get any problem we will set it to TRUE*/ 
$rollback = FALSE; 
// first we will check the directory !important 
/* use array and foreach to do that... it will make it easy and 
if you got more directory later, you just have to add it to the array... nothing more */ 
$dir = array(); 
$dir[] = 'your directory 1'; 
$dir[] = 'your directory 2'; 
$dir[] = 'your directory 3'; 
foreach ($dir as & $single_dir) { 
    if(file_exists($single_dir) == FALSE){ 
     $rollback = TRUE; 
    } 
} 
// now if the $rollback is false, we unable to create any directory... 
if($rollback==FALSE){ 
    foreach ($dir as & $single_dir){ 
     if(file_exists($single_dir)){ 
      rmdir($single_dir) 
      /* friend though I use rmdir to remove the directory but 
      it has many limitation... watch this link... 
      www.php.net/manual/en/function.rmdir.php */ 
     } 
    } 
} 
// lets check the image that we upload 
if(file_exists('image directory') == FALSE){ 
    $rollback = TRUE; 
} else { 
    if($rollback == TRUE){ 
     unlink('image directory'); /* don't use rmdir for deleting file */ 
    } 
} 

// now time to check the queries... 
if($query1 && $query2 $$ $rollback){ 
    mysql_query('COMMIT;'); 
} else { 
    mysql_query('ROLLBACK;'); 
} 

朋友我希望我的回答对你和他们有同样的问题会有很大的帮助......如果你在我的回答中发现任何错误,请原谅我,如果你能纠正我的错误...此外,如果你认为我的回答对别人有帮助,请不要忘记投票答复...谢谢你...朋友...