資料庫對比系列之三(PG事務與MySQL事務)

xuexiaogang發表於2022-05-02

我的原創連線:

資料庫對比系列之三(PG事務與MySQL事務) (qq.com)


今天網上有個帖子,說MYSQL部分事務成功,部分事務失敗。原圖如下

資料庫對比系列之三(PG事務與MySQL事務)

我第一感覺覺得不應該。我當時也覺得這個好像按照DBA的角度來說不應該一個成功一個失敗。於是我做了一個模擬。下面有兩個表一個是W表有主鍵,為了模擬衝突。另外一個B表無約束,隨便操作。

資料庫對比系列之三(PG事務與MySQL事務)

開啟事務,w有5條,b有2條。這個時候給b新增一條3,並且給w增加一條5(一定是衝突的)。資料庫版本是MySQL8.0.26。

資料庫對比系列之三(PG事務與MySQL事務)

 檢視一下結果,真的是W沒有進去,而B有資料了。好像世界觀坍塌了。和我們之前預想的不一樣。這個時候我們來看看其他資料庫如何?

     由於Oracle必須手工提交,所以很容易模擬。看下圖b取前5條。C表建立約束,給C表先增加一條資料,準備製造衝突(綠色框)。


資料庫對比系列之三(PG事務與MySQL事務)

紅色框為事務開始,給B增加一條資料,給C也增加一條資料。C寫入失敗。這個時候提交。結果是B的資料進來了,C沒有成功。看了Oracle也是這樣的機制。好了,靜心下來想想,那這麼說不是BUG了。因為Oracle不可能有這樣的BUG。畢竟大家都覺得Oracle這個神諭,有點像神一樣的存在。

資料庫對比系列之三(PG事務與MySQL事務)

來梳理一下為什麼?假設開啟事務以後,執行了SQL1,SQL2和SQL3.   SQL1成功,這個時候SQL2由於拼寫或者語法錯誤報錯執行不成功。SQL3,繼續執行成功。那麼提交以後會如何?這麼想的話(應用程式不會犯這個錯誤,因為都是編譯測試過的,但是人工會這樣的),的確應該SQL1和SQL3 成功SQL2,拼寫錯了,不成功也合理。這麼一想,我好想也想通了。也合理了。

那麼我們來看看PG的執行。B表和C表的區別是C表的ID是主鍵不能衝突的。B表一條記錄,C表一條記錄。

資料庫對比系列之三(PG事務與MySQL事務)

資料庫對比系列之三(PG事務與MySQL事務)

紅框為事務。籃框是提交,注意與其他資料庫不一樣的是。由於事務之間有報錯,所以這個提交後,PG最終給出的不是commit,而是rollback的回退。也就是說PG最後結果走的是回退,而不是提交。所以才和MySQL不一樣,當然也和Oracle不一樣。這點差異最大。那麼是不是隻要有報錯就回退呢?驗證一下:故意寫一個失敗的SQL。

資料庫對比系列之三(PG事務與MySQL事務)

果然和預期的一樣,commit後執行器覺得中間有報錯,沒有走提交的路線,而是執行了回退。

到這裡就明白了。PG在事務中不允許有任何出錯,哪怕是拼寫錯誤。否則都會全體回退。這個對於經驗豐富的人來說這沒什麼,而對於我們這種公司沒有PG、沒有TiDB,只是憑藉職業熱情來說的人還是很新鮮的。

      這裡我對比了PostgreSQL和MySQL Oracle在事務中對錯誤的分析。看到了PG對事務中出錯的0容忍。也許這些都可以通過引數修改,我還沒研究到。這裡沒有誰對誰錯。只是處理的方式不同。OracleMySQL事務中由於拼寫、約束等導致的失敗的就失敗了(約束限制,而PG這裡是強制回退)。提交那些提交成功的。如果回退則是全體回退,(執行失敗的無需回退)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/637517/viewspace-2890233/,如需轉載,請註明出處,否則將追究法律責任。

相關文章