一、事務【都是重點】
1、了解
-
一個事務其實就是一個完整的業務邏輯。
-
要么同時發生,要么同時結束。
-
是一個最小的工作單元。
-
不可再分。
看這個視頻,黑馬的,4分鐘多點就能理解到
可以理解成:
開始事務-----如果中間拋出異常,進行回滾事務---->提交事務
2、事務的四大特性(ACID)
-
1、原子性:事務是不可分割的最小操作單元,要么全部成功,要么全部失敗。
-
2、一致性:事務完成時,必須使所有的數據都保持一致狀態。
- 當轉賬操作完成時,所有賬戶的總金額應該保持不變,此時數據處于一致性狀態;如果總金額發生了改變,說明數據處于非一致性狀態。
-
3、隔離性:數據庫系統提供的隔離機制,保證事務在不受外部并發操作影響的獨立環境下運行。
- 比如張三和李四同時都在進行轉賬操作,但彼此都不影響對方。
-
4、持久性:事務一旦提交或回滾,它對數據庫中的數據的改變就是永久的。
3、事務的操作
- 創建賬戶表
CREATE TABLE account(id INT primary key AUTO_INCREMENT comment "主鍵",name VARCHAR(10) COMMENT "姓名",money INT COMMENT "余額"
)COMMENT "賬戶表";
INSERT INTO account VALUES(null,"張三",2000),(null,"李四",2000);
3.1、查看/設置事務的提交方式
SELECT @@autocommit;
SET @@autocommit = 0;--設置為0是手動提交,1是自動提交
3.2、提交事務
COMMIT;
3.3、回滾事務
ROLLBACK;
3.4、事務的舉例
CREATE TABLE account(id INT primary key AUTO_INCREMENT comment "主鍵",name VARCHAR(10) COMMENT "姓名",money INT COMMENT "余額"
)COMMENT "賬戶表";
INSERT INTO account VALUES(null,"張三",2000),(null,"李四",2000);SELECT @@autocommit;
set @@autocommit=0;--設置為手動提交-- 轉賬操作(張三給李四1000)
--1、張三的余額是多少
SELECT * FROM ACCOUNT WHERE name = "張三";
--2、將張三的余額減1000
UPDATE account SET money=money-1000 WHERE name = "張三";
lsdfjlsd
--3、將李四的余額加1000
UPDATE account SET money= money+1000 WHERE name = "李四";--提交事務
COMMIT;--回滾事務
ROLLBACK;--恢復數據
UPDATE account SET money = 2000 WHERE name = "張三" or name = '李四';
START TRANSACTION; -- 或 BEGIN
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 提交事務(持久化)
-- 或 ROLLBACK; -- 回滾事務(撤銷所有操作)
4、并發事務問題
- 臟讀(Dirty Read):
- 一個事務讀取了另一個事務未提交的更改數據。
- 如果第二個事務回滾,那么第一個事務讀取的數據將是無效的。
- 不可重復讀(Non-repeatable Read):
- 在同一事務中,多次讀取同一數據集合,但讀取的結果不同。
- 這通常是由于其他事務在兩次讀取之間更改了數據。
- 幻讀(Phantom Read):
- 在同一事務內,多次執行相同條件的查詢時,由于其他事務的插入操作,導致前后查詢結果行數不一致(出現了"幻影行")。
- 這通常是由于其他事務插入或刪除了數據。
5、事務隔離級別
- 讀未提交:允許一個事務可以看到其他事務未提交的修改。
- 讀已提交:允許一個事務只能看到其他事務已經提交的修改,未提交的修改是不可見的。
- 可重復讀:確保如果在一個事務中執行兩次相同的 SELECT 語句,都能得到相同的結果,不管其他事務是否提交這些修改。 (銀行總賬)
- 串行化:【序列化】 將一個事務與其他事務完全地隔離。
- 查看當前事務隔離級別
SELECT @@TRANSACTION_ISOLATION;
- 設置隔離級別
SESSION
:僅對當前會話有效GLOBAL
:對所有新創建的會話有效- 如果不指定,默認為SESSION
SET [SESSION|GLOBAL] TRANSANCTION ISOLATION LEVEL {READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ |SERIALIZABLE}
- 臟讀
- 創建2個終端。看黑馬視頻做的
--在終端1里做一下操作
CREATE TABLE account (id TINYINT(2) AUTO_INCREMENT PRIMARY KEY COMMENT "編號",name VARCHAR(4) NOT NULL COMMENT "姓名",money INT(4) NOT NULL COMMENT "錢")ENGINE = INNODB CHARSET=UTF8 COMMENT = "賬戶";INSERT INTO account(id,name,money) VALUES(1,"張三",2000),(2,"李四",2000);SELECT * FROM account;
#開始分終端操作
--在終端2
start transaction;
update account set money=money-1000 WHERE name = "張三";
--然后再次回到終端1
SELECT * FROM account;
會發現沒有 money - 1000 ;#因為沒有提交
--回到終端2,提交事務
COMMIT;
- 不可重復讀取
-- 事務A
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- 第一次讀取,值為1000
-- 此時事務B更新并提交了數據SELECT balance FROM accounts WHERE id = 1; -- 第二次讀取,值可能變為900(不可重復讀)
COMMIT;
- 幻讀
-- 事務A
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
SELECT * FROM accounts WHERE balance > 1000; -- 第一次查詢返回2條記錄-- 事務B在此期間執行并提交:
INSERT INTO accounts(id, balance) VALUES(3, 1500);
COMMIT;SELECT * FROM accounts WHERE balance > 1000; -- 第二次查詢仍然返回2條記錄
-- 但如果執行:
SELECT COUNT(*) FROM accounts WHERE balance > 1000; -- 可能返回3(幻讀)
COMMIT;
二、limit
1、limit startIndex ,length
-
startIndex 是起始下標,也就是展示 [startIndex+1,startIndex+5]
-
length 是長度
-- 按照薪資降序,取出排名在前5名的員工?select ename,salfromemporder by sal desclimit 0,5;
2、limit 數字
- 是指展示前“數字” 位 。
--按照薪資降序,取出排名在前5名的員工?
select ename,salfromemporder by sal desclimit 5; //取前51、2點一樣。
3、公式:
-
pageNo
:當前頁碼(通常從1開始)。 -
pageSize
:每頁顯示的記錄數。 -
(pageNo - 1) * pageSize
計算的是當前頁的第一條記錄在所有記錄中的位置。
--例如
#pageNo = 3(當前是第三頁)
#pageSize = 10(每頁顯示10條記錄)
#起始位置:(3 - 1) * 10 = 20(即從第20條記錄開始)
#每頁記錄數:10
SELECT * FROM your_table
LIMIT 20, 10;
式:
-
pageNo
:當前頁碼(通常從1開始)。 -
pageSize
:每頁顯示的記錄數。 -
(pageNo - 1) * pageSize
計算的是當前頁的第一條記錄在所有記錄中的位置。
--例如
#pageNo = 3(當前是第三頁)
#pageSize = 10(每頁顯示10條記錄)
#起始位置:(3 - 1) * 10 = 20(即從第20條記錄開始)
#每頁記錄數:10
SELECT * FROM your_table
LIMIT 20, 10;