MySQL預處理和事務


# 事務操作

* 事務概念

> 事務(transaction):事務可以由一個或多個SQL語句組成,這寫SQL語句是一個獨立的單元,這個單元是一個整體是不可分割的。如果事務中的某一個語句執行失敗,整個事務就會回滾到最初狀態。因此,只有事務中所有語句都被執行成功,這個事務才會執行成功。


> 可以通過轉賬來理解事務,只有A成功轉了,然后B成功收到了錢,才能算轉賬成功。當轉成功,但是沒有收到,應該將錢返回給A。

* 事務的ACID屬性:

事務必須有ACID屬性

原子性 Atomicity
一致性 Consistency
隔離性 Isolation 也叫孤立性
持久性 Durability

原子性: 原子型意味着意味着每個事務都必須被認為是一個不可分割的單元。整個事務中的所有操作,要么全部完成,要么全部不完成。

例如:買賣。只有買與賣都成功,才成功。不能說只有買或者只有賣

一致性: 事務必須始終保持系統處於一致的狀態。

例如:對於買賣雙方,當買賣失敗了,雙方就都應該一致認為失敗了,當買賣成功了,雙方都一致認為買賣成功了。

隔離性:每個事務對於數據庫執行來說都是不可拆分的最小單元,所以每個事務都有着自己獨立的副本,由數據庫進行執行與操作。

例如:A與B的買賣,C與D的買賣互不干擾。

持久性:事務在運行成功之后,數據會持久保存到數據庫上。

* 事務注意的問題

1. 只有innodb引擎支持事務

* mysql的事務處理語法

//開啟一個事務
mysql> begin

//做保存點
mysql> savepoint 保存點名稱

//事務回滾
mysql> rollback

或 回滾到某個保存點
mysql> rollback to 保存點名稱

//事務確認
mysql> commit

寫到begin與commit 或 begin與rollback之間的sql語句就是一個事務。

另外開啟事務也可以使用 start transaction;

* 事務處理例子

1. 模擬銀行轉賬

create table account(

id int primary key auto_increment,
uid int not null,
money decimal(19,2) not null default 0.00
)engine=innodb default charset=utf8;

//插入測試數據
insert into account(uid,money) values(3,1000);
insert into account(uid,money) values(8,2000);

//開啟事務
mysql> begin;

mysql> update account set money=money-300 where uid=3;

//設置一個還原點
mysql> savepoint jian

mysql> update account set money=money+300 where uid=8;

//設置一個還原點
mysql> savepoint jia

//如果事務中的sql語句都執行成功就提交事務
mysql>commit;

或 如果事務中的sql語句只要有一條執行失敗,就回滾
mysql> rollback;

# MySQL預處理

* 概念

預處理的意思是先提交sql語句到mysql服務端,執行預編譯,客戶端執行sql語句時,只需上傳輸入參數即可,這點和存儲過程有點相似。


* 預處理工作原理

1. 預處理:創建 SQL 語句模板並發送到數據庫。預留的值使用參數 "?" 標記 。例如:INSERT INTO MyGuests VALUES(?, ?, ?)

2. 數據庫解析,編譯,對SQL語句模板執行查詢優化,並保存起來

3. 執行:最后,將應用綁定的值傳遞給參數("?" 標記),數據庫執行語句。應用可以多次執行語句,如果參數的值不一樣。


* 預處理優點

1. 預處理的執行效率相對於一般的sql執行操作,效率比較高,因為第二次執行只需要發送查詢的參數,而不是整個語句

2. 預處理可以防止sql注入,因為預處理將sql語句與數據分開發送。

* 預處理語法

//新增一個預處理語句
prepare 預處理名稱 from 'sql語句';

//執行預處理語句
execute 預處理名稱 [ using @變量名 [, @變量名1 ] ...];

//刪除預處理語句
drop prepare 預處理語句

* 預處理實例

1. 實例1
mysql> prepare stmt1 from 'select * from user';
mysql> execute stmt1;

//刪除預處理語句
mysql> execute prepare stmt1;

2. 實例2

//?為占位符,代替將要傳遞進來的值
mysql> prepare stmt2 from 'select * from user where name=?';
mysql> set @n='jack';

//將變量@n的值傳遞給?
mysql> execute stmt2 using @n;

3. 實例3

mysql> prepare stmt3 from 'update user set name=? where id=?';

mysql> set @n='jack54',@id=1;

//將變量@n給到第一個?,@id給到第二個?
mysql> execute stmt3 using @n,@id;

 


免責聲明!

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



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