數據庫的事務處理可以保證一組處理結果的正確性。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