国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

mysql事務回滾數據回滾用法與問題

2024-07-24 12:37:14
字體:
來源:轉載
供稿:網友

mysql事務回滾就是BEGIN,ROLLBACK,COMMIT三種組成了,差不就是就如果所有數據提交成功再把數據提交,否則就自動回滾數據了,這種做法多做于銀行,大型數據操作應用上.

在當前事務中確實能看到插入的記錄,最后只不過刪除了,但是AUTO_INCREMENT不會應刪除而改變值.

1、為什么auto_increament沒有回滾?

因為innodb的auto_increament的計數器記錄的當前值是保存在存內 存中的,并不是存在于磁盤上,當mysql server處于運行的時候,這個計數值只會隨著insert改增長,不會隨著delete而減少。而當mysql server啟動時,當我們需要去查詢auto_increment計數值時,mysql便會自動執行:SELECT MAX(id) FROM 表名 FOR UPDATE;語句來獲得當前auto_increment列的最大值,然后將這個值放到auto_increment計數器中。所以就算 Rollback MySQL的auto_increament計數器也不會作負運算。

2、MySQL的事務對表操作的時候是否是物理操作?

MySQL的事務是有redo和undo的,redo操作的所有信息都是記錄到 redo_log中,也就是說當一個事務做commit操作時,需要先把這個事務的操作寫到redo_log中,然后再把這些操作flush到磁盤上,當 出現故障時,只需要讀取redo_log,然后再重新flush到磁盤就行了。

而對于undo就比較麻煩,MySQL在處理事務時,會在數據共享 表空間里申請一個段叫做segment段,用保存undo信息,當在處理rollback,不是完完全全的物理undo,而是邏輯undo,就是說會對之 前的操作進行反操作,但是這些共享表空間是不進行回收的。這些表空間的回收需要由mysql的master thread進程來進行回收。

首先,mysql使用事務前需確定存儲引擎為innodb,事務代碼如下:

start transaction rollback  commit

修改表類型,代碼如下:

  1. ALTER TABLE `goods` ENGINE = InnoDB; engine 
  2. ALTER TABLE `goods` ENGINE = MYISAM  
  3. show create table goods G 

下面為存儲過程的代碼:

  1. BEGIN 
  2. DECLARE t_error INTEGER DEFAULT 0;  
  3. DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; 
  4. #set autocommit =0; 
  5. START TRANSACTION
  6. INSERT INTO `mytest`.`test2` VALUES ( 1 ,’22′,’33′); 
  7. INSERT INTO `mytest`.`test2` VALUES ( NULL ,’22′,’33′); 
  8. IF t_error = 1 THEN  
  9. ROLLBACK;  
  10. ELSE  
  11. COMMIT;  
  12. END IF; 
  13. END 

上面只是mysql事物回滾了,下面我來介紹一個與php結合的實例,例子代碼如下:

  1. $lnk = mysql_connect("localhost""root""");    
  2. mysql_select_db("test");    
  3. mysql_query("BEGIN");    
  4. $query = mysql_query("INSERT INTO test VALUES(1, 'yangjun')");    
  5. $q1 = mysql_error();    
  6. mysql_query("INSERT INTO test VALUES(1, 'yangjun')");    
  7. $q2 = mysql_error();    
  8. mysql_query("INSERT INTO test VALUES(2, '楊俊')");    
  9. $q3 = mysql_error();    
  10. if (!$q1 && !$q2 && !$q3) {    
  11.      mysql_query("COMMIT");  //全部成功,提交執行結果  
  12. else {    //Vevb.com 
  13.      mysql_query("ROLLBACK"); //有任何錯誤發生,回滾并取消執行結果    
  14. }    
  15. var_dump($q1$q2$q3); 

例子,代碼如下:

  1. ** 
  2. * 訂單入庫 
  3. * 1,生成日期+隨機數訂單號,并保證不重復 
  4. * 2,插入訂單order_info表 
  5. * 3,插入訂單對應的商品表 order_goods 
  6. * 4,修改商品表,減少庫存 
  7. * 5,用事務保證三表的一致性 
  8. */ 
  9.  
  10. /* 臨時需要一個生成訂單的功能 */ 
  11. function create_sn() 
  12. $sn = date('YmdHis').rand(100,999); 
  13. $sql = "select count(*) from order_info where order_sn = '$sn'"
  14. return $GLOBALS['db']->getOne($sql)?create_sn():$sn;  //有這個單號就重生成一個 
  15.  
  16. // ---------事務開始---------------------- 
  17. $db->query("start transaction");  
  18. // 可用此方法插入 $db->autoExecute('表名',$data,'insert/update','條件') 
  19. $order_sn     = create_sn(); 
  20. $user_id      = $_SESSION['user']['user_id']; 
  21. $add_time     = time(); 
  22. $goods_amount = $cart->getPrice(); 
  23. $sql = "insert into order_info (order_sn,user_id,goods_amount,add_time)  
  24. VALUES ('$order_sn','$user_id','$goods_amount','$add_time')"; 
  25.  
  26. $db->query($sql); // 執行插入訂單SQL語句(order_info表) 
  27.  
  28. /* 操作order_goods表 */ 
  29. $order_id = $db->insert_id(); // 取得剛插入表的主鍵 
  30. $cartlist = $cart->enumItems(); // 獲得購物車商品的數組 
  31. foreach ($cartlist as $k=>$v
  32. //查出商品的SN等信息加到購物車商品的數組中 
  33. $sql = "select goods_id,goods_sn,goods_name,shop_price from goods where goods_id = '$k'"
  34. $cartlist[$k] = $cartlist[$k] + $db->getRow($sql);   
  35. /* 根據購物車里的商品,將所有要買的商品添加到order_goods表里,并更新goods表的庫存 */ 
  36. $sqls=array(); 
  37. foreach ($cartlist as $k=>$v
  38. $goods_id     = $k
  39. $goods_name   = $v['goods_name']; 
  40. $goods_sn     = $v['goods_sn']; 
  41. $goods_number = $v['num']; 
  42. $goods_price  = $v['shop_price'] * $v['num']; 
  43. $sqls[] = "insert into order_goods (order_id,goods_id,goods_name,goods_sn,goods_number,goods_price) values ('$order_id','$goods_id','$goods_name','$goods_sn','$goods_number','$goods_price')"
  44. $sqls[] = "update goods set goods_number = goods_number - '$goods_number' where goods_id = '$goods_id'"
  45. //print_r($sqls); 
  46. $res = true; 
  47. foreach ($sqls as $sql
  48.  
  49. $res = $res && $db->query($sql); //如果有一個SQL語句出錯,$res就不為真 
  50. // ---------如果$res是真就提交事務,否則就回滾事務---------- 
  51.  
  52. if(!$res
  53. {  
  54. $db->query('rollback'); 
  55. show_message('訂單創建失敗','返回購物車','flow.php?act=cartinfo'); 
  56. exit(); 
  57. else  
  58. $db->query('commit'); 
  59. $smarty->assign('order_sn',$order_sn); 
  60. $smarty->assign('order_amount',$cart->getPrice()); 
  61. $cart->emptyItems(); 
  62. $smarty->display('my_gwc3.html'); 

注意:MYSQL中只有INNODB和BDB類型的數據表才能支持事務處理,其他的類型是不支持的.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 涪陵区| 绵竹市| 临洮县| 温州市| 永福县| 清原| 轮台县| 崇义县| 和平区| 金沙县| 皋兰县| 西丰县| 左贡县| 惠安县| 阜南县| 平南县| 达拉特旗| 汨罗市| 赤壁市| 梁山县| 长丰县| 房产| 马公市| 南皮县| 根河市| 四子王旗| 铁岭县| 儋州市| 久治县| 阿城市| 中西区| 闻喜县| 南丰县| 玉林市| 漯河市| 南京市| 安顺市| 理塘县| 石棉县| 台州市| 大安市|