mysql的事務處理與鎖表


數據庫的事務處理可以保證一組處理結果的正確性。mysql中只有INNODB和BDB引擎的數據表才支持事務處理,對於不支持事務的MyISAM引擎數據庫可以使用表鎖定的方法來實現相同的功能。

  mysql的事務處理主要有兩種方法來實現。

  1、用begin,rollback,commit來實現。

  begin 開始一個事務

  rollback 事務回滾

  commit 事務確認

  Php代碼

$conn = mysql_connect('localhost','root','root') or die ("數據連接錯誤!!!");

mysql_select_db('test',$conn);

mysql_query("set names 'utf8'");

//開始一個事務

mysql_query("BEGIN"); //或者mysql_query("START TRANSACTION");

$sql = "INSERT INTO `t_user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";

$sql2 = "INSERT INTO `t_user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//這條是故意寫錯

$res = mysql_query($sql);

$res1 = mysql_query($sql2);

if($res && $res1){

mysql_query("COMMIT");

echo '提交成功。';

}else{

mysql_query("ROLLBACK");

echo '數據回滾。';

}

mysql_query("END");

  2、直接用set來改變mysql的自動提交模式

  MYSQL默認是自動提交的,也就是你提交一個QUERY,它就直接執行!我們可以通過

  set autocommit=0 禁止自動提交

  set autocommit=1 開啟自動提交

  Php代碼

$conn = mysql_connect('localhost','root','root') or die ("數據連接錯誤!!!");

mysql_select_db('test',$conn);

mysql_query("set names 'utf8'");

mysql_query("SET AUTOCOMMIT=0"); //設置mysql不自動提交,需自行用commit語句提交

$sql = "INSERT INTO `t_user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";

$sql2 = "INSERT INTO `t_user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//這條故意寫錯

$res = mysql_query($sql);

$res1 = mysql_query($sql2);

if($res && $res1){

mysql_query("COMMIT");

echo '提交成功。';

}else{

mysql_query("ROLLBACK");

echo '數據回滾。';

}

mysql_query("END"); //事務處理完時別忘記mysql_query("SET AUTOCOMMIT=1");自動提交

  對於不支持事務的MyISAM引擎數據庫可以使用表鎖定的方法來實現

  MyISAM & InnoDB 都支持,LOCK TABLES可以鎖定用於當前線程的表。如果表被其它線程鎖定,則造成堵塞,直到可以獲取所有鎖定為止。UNLOCK TABLES可以釋放被當前線程保持的任何鎖定。當線程發布另一個LOCK TABLES時,或當與服務器的連接被關閉時,所有由當前線程鎖定的表被隱含地解鎖。

  Php代碼

mysql_query("LOCK TABLES `t_user` WRITE");//鎖住`user`表

$sql = "INSERT INTO `t_user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";

$res = mysql_query($sql);

if($res){

echo '提交成功。!';

}else{

echo '失敗!';

}

mysql_query("UNLOCK TABLES");//解除鎖定

  如果操作表比較多,采用斷點調試的時候,在事務處理完成之前(COMMIT)查看數據庫的相關表是看不到表中數據的變化的。

  下面是在mysql存儲過程中使用事務處理的一個例子。

  Java代碼

CREATE PROCEDURE TransTest(in p1 VARCHAR(20),in p2 VARCHAR(50))

BEGIN

declare err int default 0;

/*如果出現sql異常,則將err設置為1后繼續執行后面的操作 */

declare continue handler for sqlexception set err=1; -- 出錯處理

set autocommit = 0;

insert into sy_queryconfig(syq_id) values(p1);

insert into sy_queryconfig(syq_id) values(p2);

if err=1 then

ROLLBACK;

ELSE

COMMIT;

end if;

END

  PS:附加一個mysql數據庫在delete表數據的時候,不能用別名操作,例如:

  delete from t_user where id in (1,2);//此寫法正確delete from t_user t where t.id in (1,2);//此寫法錯誤

  mysql就是這么任性!

技術分享:www.kaige123.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM