003 事務到底可見不可見

2021-10-09 06:59:17 字數 3046 閱讀 9352

檢視資料庫的事務配置:

mysql> show variables like 'transaction_isolation';

+-----------------------+----------------+

| variable_name | value |

+-----------------------+----------------+

| transaction_isolation | read-committed |

+-----------------------+----------------+

1、什麼是事務

事務是指一條或者一組語句 組成乙個單元,這個單元要麼都成功要麼都失敗。

例如:張三有1000元,李四有1000元;但是 張三給了李四400,那麼李四就有1000,張三還剩 500;

update table user set money=500 where name = "張三";

update table user set money=1500 where name = "李四";

那麼 我們肯定要保證這兩條語句要麼都成功,要麼都失敗。這時候就用到了事務。

2、事務的4大特性(acid

a(原子性 atomicity):

原子性指事務是不可分割的,要麼都執行成功,要麼都失敗;

c(一致性consistency):

事務必須使得資料庫狀態從乙個一致性狀態,變為另乙個一致性狀態;

i(隔離性 isolation):

指乙個事務的執行,不被其他事務所影響;

d(永續性durability):

永續性指乙個事務一旦提交之後 對資料庫餓修改是永久的;

事務其實可以分為兩大類:隱式事務 和 顯示事務

隱式事務:set implicit_transactions on

比如我們 select、insert、update、delete  都是隱式事務;

顯示事務

指帶有明顯開始和結束標記;

步驟一:禁用自動提交

set autocommit = 0;

步驟二:開啟事務

start transaction;

步驟三:sql 語句

update table user set money=500 where name = "張三";

update table user set money=1500 where name = "李四";

步驟四:結束事務 --> 顯示提交或回滾

commit 或 rollback;

自動提交事務:

指一旦執行 自動提交;

上面說的事務,單個執行都不會有問題,但是當多個事務同時執行的時候,就會出現經典的三個問題,

髒讀,幻讀,不可重複讀;

髒讀兩個事務,事務a讀取了一條事務b修改過的資料,事務b發現不對,我不能修改,進行了事務回滾,事務a 讀到的就是無效的資料;

不可重複讀:

兩個事務,事務a多次讀取同一條資料,事務b在事務a讀取的過程中,不斷的修改並提交這條資料,導致事務a讀到的資料不一致;

幻讀:兩個事務,事務a根據某個條件,讀取了一些資料,事務b,插入或刪除滿足這個條件的資料,導致事務a再次讀取的時候,發現一會變多一會變少;

總結: 從上面來看,很多人或混淆 不可重複讀 和 幻讀,其實這兩個側重點不同,不可能重複讀 側重的是 修改資料;而幻讀側重的是 新增或刪除;

事務隔離級別

髒讀不可重複讀

幻讀讀未提交(read-uncommitted)是是

是不可重複讀(read-committed)否是

是可重複讀(repeatable-read)否否

是序列化(serializable)否否

否 mysql 預設隔離級別是:rr (repeatable- read),oracle預設是:rc(read-committed);

使用了mvvc 的控制方式,即mutil-version concurrency control,多版本併發控制,類似於樂觀鎖的一種實現方式。

實現方式:

innodb在每行記錄後面儲存兩個隱藏的列來,分別儲存了這個行的建立時間和行的刪除時間。這裡儲存的並不是實際的時間值,而是系統版本號,當資料被修改時,版本號加1在讀取事務開始時,系統會給當前讀事務乙個版本號,事務會讀取版本號<=當前版本號的資料此時如果其他寫事務修改了這條資料,那麼這條資料的版本號就會加1,從而比當前讀事務的版本號高,讀事務自然而然的就讀不到更新後的資料了

假設初始版本號為1:

insert into user (id,name) values (1,'tom');
id

name

create_version

delete_version

1tom

1

select * from user where id = 1;
此時讀到的版本號為1

update user set name = 'jerry' where id = 1;
在更新操作的時候,該事務的版本號在原來的基礎上加1,所以版本號為2。

先將要更新的這條資料標記為已刪除,並且刪除的版本號是當前事務的版本號,然後插入一行新的記錄

idname

create_version

delete_version

1tom12

1jerry

2此時事務a再重新讀資料:

select * from user where id = 1;
由於事務a一直沒提交,所以此時讀到的版本號還是為1,所以讀到的還是tom這條資料,也就是可重複讀

delete from user where id = 1;
在刪除操作的時候,該事務的版本號在原來的基礎上加1,所以版本號為3

刪除時,將當前版本號作為刪除版本號

idname

create_version

delete_version

1jerry23

參考文件:

不可見的unicode字元

專案中執行到 如 x x.encode encoding 報錯 latin 1 codec can t encode character u u202d in position 0 ordinal not in range 256 可見是編碼問題。報錯資訊顯示這個x字串中含有異常的字元u u202d...

Vim中顯示不可見字元

在linux中,cat a file可以把檔案中的所有 可見的和不可見的字元 都顯示出來,在vim中,如何將不可見字元也顯示出來呢?當然,如果只是想在vim中檢視的話,可以這樣 cat a在vim中呼叫cat轉換顯示。這樣的做法不便於編輯,其實vim本身是可以設定顯示不可見字元的。只需要 set i...

git 出現 swp不可見檔案

swp檔案是如何生成的?正常情況 當你開啟乙個檔案時,vi會自動生成乙個.swp檔案,檔名為 filename.swp,如果你正常退出,swp檔案會自動刪除。解決辦法 1 為避免同個檔案產生兩個不同的版本,請使用readonly模式 2 使用vi r filename 恢復,然後把.swp檔案刪除 ...