MySQL事務的一些奇奇怪怪知識

Gorm事務有error卻不返回會發生什么

Gorm包是大家比較高頻使用。正常的用法是,如果有失敗返回error,整體rollback,如果不返回error則commit。下面是Transaction的源碼:

// Transaction start a transaction as a block, return error will rollback, otherwise to commit. Transaction executes an
// arbitrary number of commands in fc within a transaction. On success the changes are committed; if an error occurs
// they are rolled back.
func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err error) {panicked := trueif committer, ok := db.Statement.ConnPool.(TxCommitter); ok && committer != nil {// nested transactionif !db.DisableNestedTransaction {err = db.SavePoint(fmt.Sprintf("sp%p", fc)).Errorif err != nil {return}defer func() {// Make sure to rollback when panic, Block error or Commit errorif panicked || err != nil {db.RollbackTo(fmt.Sprintf("sp%p", fc))}}()}err = fc(db.Session(&Session{NewDB: db.clone == 1}))} else {tx := db.Begin(opts...)if tx.Error != nil {return tx.Error}defer func() {// Make sure to rollback when panic, Block error or Commit errorif panicked || err != nil {tx.Rollback()}}()if err = fc(tx); err == nil {panicked = falsereturn tx.Commit().Error}}panicked = falsereturn
}

神奇用法

但如果我瞎搞呢?如果有error我仍然返回nil,會發生什么?

err := db.Transaction(func(tx *gorm.DB) error {var err errorisInserted, err = d.TxCreate(tx, record)if err != nil {return nil}err = d.TxUpdate(tx, opt)if err != nil {return errors.Wrap(err, "failed to update")}return nil})

解釋

這種情況下,本質看MySQL自身的設計。事務具有原子性,理論上應該要么全部成功,要么全部失敗。但如果在一條語句失敗后執行COMMIT,MySQL 會盡力提交已成功執行的語句。例如:

START TRANSACTION;
INSERT INTO test (id, value) VALUES (2, 'data3'); 
INSERT INTO test (id, value) VALUES (3, 'data4'); 
-- 故意讓這條語句失敗(假設id沖突)
INSERT INTO test (id, value) VALUES (2, 'data5'); 
COMMIT; 

在上述例子中,前兩條INSERT語句可能已經成功執行并修改了數據庫,而第三條失敗。執行COMMIT后,前兩條語句的修改會被永久保存到數據庫中,而失敗的語句不會回滾整個事務。

其實十分不建議這么用。數據庫狀態可能會出現部分操作生效,部分未生效的情況,破壞了事務的原子性。這可能導致數據不一致問題,例如業務邏輯上要求某些數據必須同時存在或不存在,但由于這種部分提交的情況,無法保證這種一致性。

MySQL表數據時間的記錄時刻

假設數據庫是這樣的

CREATE TABLE `conversation_new_message` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',`conversation_new_id` bigint unsigned NOT NULL COMMENT '自增id',`message` json DEFAULT NULL COMMENT 'conversation history, a json map',`turn` bigint NOT NULL COMMENT '輪數',`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '上一次更新時間',PRIMARY KEY (`id`),
) ENGINE=InnoDB

起一個事務,按照下面的時間點執行,最終的創建時間是多少?是按照insert時刻的時間來的(不同記錄不一樣),還是按照真正落庫的時間來的(不同記錄一樣)?

在這里插入圖片描述

發現是按照真正寫入的時間來的。其實也比較好理解,雖然我們沒有直接賦值,但CURRENT_TIMESTAMP本身在記錄創建的時候就已經設置好值了。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83593.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83593.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83593.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

時序數據庫、實時數據庫與實時數倉:如何為實時數據場景選擇最佳解決方案?

隨著物聯網、金融交易、在線游戲等場景對實時數據處理需求的增長,市場上涌現出多種專門針對實時數據處理的數據庫解決方案。然而,面對時序數據庫、實時數據庫和實時數據倉庫這三種看似相似的技術,許多技術決策者常常感到困惑:它們…

Spring3+Vue3項目中的知識點——JWT

全稱:JOSN Web Token 定義了一種簡潔的、自包含的格式,用于通信雙方以json數據格式的安全傳輸信息 組成: 第一部分:Header(頭),記錄令牌類型、簽名算法等。 第二部分:Payload&am…

微服務架構詳解

微服務架構詳解:從概念到實踐(附代碼案例) 目錄 微服務架構詳解:從概念到實踐(附代碼案例) 一、微服務架構概述 1.1 什么是微服務? 1.2 微服務的核心思想 二、微服務架構的優勢與挑戰 2.1 優勢 2.2 挑戰 三、微服務架構的核心組件 3.1 服務注冊與發現 示例代…

linux下編寫shell腳本一鍵編譯源碼

0 前言 進行linux應用層編程時,經常會使用重復的命令對源碼進行編譯,然后把編譯生成的可執行文件拷貝到工作目錄,操作非常繁瑣且容易出錯。本文編寫一個簡單的shell腳本一鍵編譯源碼。 1 linux下編寫shell腳本一鍵編譯源碼 shell腳本如下&…

學習!FastAPI

目錄 FastAPI簡介快速開始安裝FastApiFastAPI CLI自動化文檔 Reqeust路徑參數Enum 類用于路徑參數路徑參數和數值校驗 查詢參數查詢參數和字符串校驗 請求體多個請求體參數嵌入單個請求體參數 CookieHeader表單文件直接使用請求 ResponseResponse Model多個關聯模型 響應狀態碼…

DAY 4 缺失值的處理

\1. 打開數據 import pandas as pd data pd.read_csv(rdata.csv) data\2. 查看數據 # 打印數據集的基本信息(列名、非空值數量、數據類型等) print("data.info() - 數據集的基本信息(列名、非空值數量、數據類型等)&#…

Java面試實戰:從Spring Boot到分布式緩存的深度探索

Java面試實戰:從Spring Boot到分布式緩存的深度探索 場景介紹 在一家著名的互聯網大廠,面試官老王正對求職者“水貨程序員”明哥進行Java技術面試。明哥帶著一點緊張和自信,迎接這場技術“拷問”。 第一輪:基礎問題 老王&#…

UART、SPI、IIC復習總結

一、UART 1、UART和USART的異同? 相同點 基本功能:都是用于串行通信的數據收發設備,能夠實現數據在不同設備之間的傳輸。在異步通信模式下,二者的工作方式相似,都使用起始位、數據位、校驗位(可選&#…

PostGIS實現矢量數據轉柵格數據【ST_AsRaster】

ST_AsRaster函數應用詳解:將矢量數據轉換為柵格數據 [文章目錄] 一、函數概述 二、函數參數與分組說明 三、核心特性與注意事項 四、示例代碼 五、應用場景 六、版本依賴 七、總結 一、函數概述 ST_AsRaster是PostGIS中用于將幾何對象(如點、線…

Linux 線程(上)

前言:大家早上中午晚上好!!今天來學習一下linux系統下所謂的線程吧!!! 一、重新理解進程,什么是進程? 1.1 圖解 其中黑色虛線部分一整塊就是進程,注意:一整…

Java API學習筆記

一.類 1. String 類 不可變性:String對象創建后不可修改,每次操作返回新對象 String str "Hello"; str.length(); str.charAt(0); str.substring(1, 4); str.indexOf("l"); str.equals("hel…

醫療信息系統安全防護體系的深度構建與理論實踐融合

一、醫療數據訪問系統的安全挑戰與理論基礎 1.1 系統架構安全需求分析 在醫療信息系統中,基于身份標識的信息查詢功能通常采用分層架構設計,包括表現層、應用層和數據層。根據ISO/IEC 27001信息安全管理體系要求,此類系統需滿足數據保密性…

5.18本日總結

一、英語 復習list3list28 二、數學 學習14講部分內容,1000題13講部分 三、408 學習計網5.3剩余內容 四、總結 計網TCP內容比較重要,連接過程等要時常復習;高數學到二重積分對定積分的計算相關方法有所遺忘,需要加強鞏固。…

MATLAB2025新功能

截至2023年9月,MATLAB官方尚未公布2025版本的具體更新內容。根據歷史更新規律和技術發展趨勢,未來版本可能會在以下方面進行優化: AI與深度學習增強 可能新增自動化模型壓縮工具強化生成式AI模型支持改進的ONNX格式轉換接口 性能提升 矩陣運…

算法題(149):矩陣消除游戲

審題: 本題需要我們找到消除矩陣行與列后可以獲得的最大權值 思路: 方法一:貪心二進制枚舉 這里的矩陣消除時,行與列的消除會互相影響,所以如果我們先統計所有行和列的總和,然后選擇消除最大的那一行/列&am…

Uniapp、Flutter 和 React Native 全面對比

文章目錄 前言Uni-app、Flutter 和 React Native 跨平臺框架對比報告1. 性能對比2. 跨平臺能力3. 學習曲線4. 社區生態與第三方庫5. 原生能力擴展6. UI 渲染能力7. 企業支持與典型使用場景8. 開發效率與工具鏈 前言 將對 Uniapp、Flutter 和 React Native 進行全面對比&#x…

JAVA SE 多線程(上)

文章目錄 📕1. Thread類及常見方法??1.1 創建線程??1.2 Thread 的常見構造方法??1.3 Thread 的幾個常見屬性??1.4 啟動一個線程---start()??1.5 中斷一個線程---interrupt()??1.6 等待一個線程---join()??1.7 獲取當前線程引用??1.8 休眠當前線程 &…

Linux云計算訓練營筆記day10(MySQL數據庫)

Linux云計算訓練營筆記day10(MySQL數據庫) 目錄 Linux云計算訓練營筆記day10(MySQL數據庫)ifnull別名聚合函數group byHAVING 子查詢關聯查詢 ifnull 在DQL語句中可以使用函數或表達式 函數 IFNULL(arg1,arg2) 如果arg1為NULL,函…

上位機知識篇---流式Web服務器模式的實現

文章目錄 前言 前言 本文簡單介紹了流式Web服務器模式的實現。

Dify與n8n全面對比指南:AI應用開發與工作流自動化平臺選擇【2025最新】

Dify與n8n全面對比指南:AI應用開發與工作流自動化平臺選擇【2025最新】 隨著AI技術與自動化工具的迅速發展,開發者和企業面臨著多種平臺選擇。Dify和n8n作為兩個備受關注的自動化平臺,分別專注于不同領域:Dify主要面向AI應用開發&…