為什麼mysql事務回滾後, 自增ID依然自增

2022-07-02 18:12:16 字數 1664 閱讀 9307

事務回滾後,自增id仍然增加,回滾後,自增id仍然增加。

比如當前id是7,插入一條資料後,又回滾了。然後你再插入一條資料,此時插入成功,這時候你的id不是8,而是9。因為雖然你之前插入回滾,但是id還是自增了。

如果你認為自增id不應該被事務化,那麼其他事務不得不等待著,檢查自增id是被使用還是被回滾,這就導致阻塞。

比如下面的例子,a表使用自增id。

user 1

------------begin transaction

insert into a ...

insert into b ...

update c ...

insert into d ...

commit

user 2

-----------begin transaction

insert into a ...

insert into b ...

commit

看以上的例子**,如果自增id也要被事務化,那麼假設user 2 的事務在user 1執行後的1毫秒後執行,那麼他的插入到a表不得不等待user 1的整個事務結束,檢查第乙個自增id是不是被使用了,這就導致阻塞。

自增id不被事務化是設計使然,不是bug,如果需要緊密連續的自增序列,建議採用其他方法生成。

mysql事務回滾資料回滾用法與問題

mysql事務回滾就是begin,rollback,commit三種組成了,差不就是就如果所有資料提交成功再把資料提交,否則就自動回滾資料了,這種做法多做於銀行,種大大型資料操作應用上。

在當前事務中確實能看到插入的記錄。最後只不過刪除了。但是auto_increment不會應刪除而改變值。

1、為什麼auto_increament沒有回滾?

因為innodb的auto_increament的計數器記錄的當前值是儲存在存內 存中的,並不是存在於磁碟上,當mysql server處於執行的時候,這個計數值只會隨著insert改增長,不會隨著delete而減少。而當mysql server啟動時,當我們需要去查詢auto_increment計數值時,mysql便會自動執行:select max(id) from 表名 for update;語句來獲得當前auto_increment列的最大值,然後將這個值放到auto_increment計數器中。所以就算 rollback mysql的auto_increament計數器也不會作負運算。

2、mysql的事務對錶操作的時候是否是物理操作?

mysql的事務是有redo和undo的,redo操作的所有資訊都是記錄到 redo_log中,也就是說當乙個事務做commit操作時,需要先把這個事務的操作寫到redo_log中,然後再把這些操作flush到磁碟上,當 出現故障時,只需要讀取redo_log,然後再重新flush到磁碟就行了。

而對於undo就比較麻煩,mysql在處理事務時,會在資料共享 表空間裡申請乙個段叫做segment段,用儲存undo資訊,當在處理rollback,不是完完全全的物理undo,而是邏輯undo,就是說會對之 前的操作進行反操作,但是這些共享表空間是不進行**的。這些表空間的**需要由mysql的master thread程序來進行**。

參考:mysql事務回滾資料回滾用法與問題 

事務回滾後,自增id仍然增加

**:

為什麼mysql事務回滾後,自增ID依然自增

因為innodb的auto increament的計數器記錄的當前值是儲存在存內 存中的,並不是存在於磁碟上,當mysql server處於執行的時候,這個計數值只會隨著insert改增長,不會隨著delete而減少。而當mysql server啟動時,當我們需要去查詢auto increment計...

事務回滾後,自增ID仍然增加。

回滾後,自增id仍然增加。比如當前id是7,插入一條資料後,又回滾了。然後你再插入一條資料,此時插入成功,這時候你的id不是8,而是9.因為雖然你之前插入回滾,但是id還是自增了。如果你認為自增id不應該被事務化,那麼其他事務不得不等待著,檢查自增id是被使用還是被回滾,這就導致阻塞。比如下面的例子...

事務回滾後,自增ID仍然增加

回滾後,自增id仍然增加。比如當前id是7,插入一條資料後,又回滾了。然後你再插入一條資料,此時插入成功,這時候你的id不是8,而是9.因為雖然你之前插入回滾,但是id還是自增了。如果你認為自增id不應該被事務化,那麼其他事務不得不等待著,檢查自增id是被使用還是被回滾,這就導致阻塞。比如下面的例子...