在單使用者模式,事務非常容易了解 — 它們隻是和儲存或忘記應用程式的狀态有關。然而,在多使用者模式中,事務變得複雜多了。多使用者事務的經典說明是銀行帳戶,其中一個應用程式試圖在借記帳戶,同時另一個應用程式試圖貸記同一個帳戶。如果您熟悉并發程式設計(也叫作多線程程式設計),您以前可能見過這種問題。根本的問題是除非兩個事務互相隔離,否則一個應用程式就可能影響另一個,進而導緻錯誤的程式狀态。在我們簡單的說明中,這可能意味着一個帳戶中有錯誤的金額,這将無益于留住客戶。
當處理多個通路相同資料的使用者時,通常可能出現三種問題:
- 髒讀。當應用程式使用了被另一個應用程式修改過的資料,而這個資料處于未送出狀态時,就會發生髒讀。第二個應用程式随後會請求復原被其修改的資料。第一個事務使用的資料就會被損壞,或者“變髒”。
- 不可重複的讀。當一個事務獲得了資料,而該資料随後被一個單獨的事務所更改時,若第一個事務再次讀取更改後的資料,就會發生不可重複的讀。這樣,第一個事務進行了一個不可重複的讀。
- 虛讀。當事務通過某種查詢擷取了資料,另一個事務修改了部分該資料,原來的事務第二次擷取該資料時,就會發生虛讀。第一個事務現在會有不同的結果集,它可能包含虛讀。
MYSQL--事務處理 2 0 07年 06月19日星期二 22:17 MYSQL的事務處理功能
事務處理在各種管理系統中都有着廣泛的應用,比如人員管理系統,很多同步資料庫操作大都需要用到事務處理。比如說,在人員管理系統中,你删除一個人員,你即需要删除人員的基本資料,也要删除和該人員相關的資訊,如信箱,文章等等,這樣,這些資料庫操作語句就構成一個事務!
删除的SQL語句
delete from userinfo where ~~~
delete from mail where ~~
delete from article where~~
~~
如果沒有事務處理,在你删除的過程中,假設出錯了,隻執行了第一句,那麼其後果是難以想象的!
但用事務處理。如果删除出錯,你隻要rollback就可以取消删除操作(其實是隻要你沒有commit你就沒有确實的執行該删除操作)
一般來說,在商務級的應用中,都必須考慮事務處理的!
檢視inodb資訊
shell> /usr/local/mysql -u root -p
mysql> show variables like "have_%"
系統會提示:
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_bdb | YES |
| have_crypt | YES |
| have_innodb | YES |
| have_isam | YES |
| have_raid | YES |
| have_symlink | YES |
| have_openssl | NO |
| have_query_cache | YES |
+------------------+-------+
8 rows in set (0.05 sec)
如果是這樣的,那麼我們就可以建立一張支援事務處 理的表來試試了。
MYSQL的事務處理功能!
作者:Feifengxlq Email:[email protected]
一 直以來我都以為MYSQL不支援事務處理,是以在處理多個資料表的資料時,一直都很麻煩(我是不得不将其寫入文本檔案,在系統重新加載得時候才寫入資料庫以防出錯)~今天發現MYSQL資料庫從4.1就開始支援事務功能,據說 5.0将引入存儲過程^_^
先簡單介紹一下事務吧!事務是DBMS得執行機關。它由有限得資料庫操作序列組成得。但不是任意得資料庫操作序列都能成為事務。一般來說,事務是必須滿足4個條件(ACID)
原子性(Autmic):事務在執行性,要做到“要麼不做,要麼全做!”,就是說不允許事務部分得執行。即使因為故障而使事務不能完 成,在rollback時也要消除對資料庫得影響!
一緻性(Consistency):事務得操作應該使使資料庫從一個一緻狀态轉變倒另一個一緻得狀态!就拿網上購物來說吧,你隻有即讓商品出庫,又讓商品進入顧客得購物籃才能構成事務!
隔離性(Isolation):如果多個事務并 發執行,應象各個事務獨立執行一樣!
持久性(Durability):一個成功執行得事務對資料庫得作用是持久得,即使資料庫應故障出錯,也應該能夠恢複!
MYSQL的事務處理主要有兩種方法。
1、用begin,rollback,commit來實作
begin 開始一個事務
rollback 事務復原
commit 事務确認
2、直接用set來改變mysql的自動送出模式
MYSQL預設是自動送出的,也就是你送出一個QUERY,它就直接執行!我們可以通過
set autocommit=0 禁止自動送出
set autocommit=1 開啟自動送出
來實作事務的處理。
但注意當你用 set autocommit=0 的時候,你以後所有的SQL都将做為事務處理,直到你用commit确認或rollback結束,注意當你結束這個事務的 同時也開啟了個新的事務!按第一種方法隻将目前的作為一個事務!
個人推薦 使用第一種方法!
MYSQL中隻有INNODB和BDB類型的資料表才能支援事務處 理!其他的類型是不支援的!(切記!)
下次有空說下MYSQL的資料表的鎖定和解鎖!
MYSQL5.0 WINXP下測試通過~ ^_^
mysql> use test;
Database changed
mysql> CREATE TABLE `dbtest`(
-> id int(4)
-> ) TYPE=INNODB;
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql> select * from dbtest
-> ;
Empty set (0.01 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest value(5);
Query OK, 1 row affected (0.00 sec)
mysql> insert into dbtest value(6);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest values(7);
Query OK, 1 row affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql>
*******************************************************************************************************************
[PHP]
function Tran( $sql ) {
$judge = 1;
mysql_query('begin');
foreach ($sql as $v) {
if ( !mysql_query($v) ) {
$judge = 0;
}
}
if ($judge == 0) {
mysql_query('rollback');
return false;
}
elseif ($judge == 1) {
mysql_query('commit');
return true;
}
}
[/PHP]
************************************************
<?php
$handler=mysql_connect("localhost","root","");
mysql_select_db("task");
mysql_query("SET AUTOCOMMIT=0");// 設定為不自動送出,因為MYSQL預設立即執行
mysql_query("BEGIN");//開始事務定義
if(!mysql_query("insert into trans (id) values('2')"))
{
mysql_query("ROOLBACK");// 判斷當執行失敗時復原
}
if(!mysql_query("insert into trans (id) values('4')"))
{
mysql_query("ROOLBACK");//判斷執行失敗復原
}
mysql_query("COMMIT");// 執行事務
mysql_close($handler);
?>