日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql事务 mysql事务回滚 MySQL事务死锁 如何解除死锁 资金出入账

發(fā)布時間:2024/3/12 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql事务 mysql事务回滚 MySQL事务死锁 如何解除死锁 资金出入账 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這里寫目錄標題

  • 問題
    • 什么是事務
    • 為什么需要事務
      • 創(chuàng)建賬戶表
      • 插入數(shù)據(jù)
      • 無事務資金出入賬
      • 有事務資金出入賬
  • 事務死鎖
    • 死鎖出現(xiàn)的原因
    • 解決事務死鎖
      • 查看表級鎖
      • 查詢表鎖進程
      • 查詢行級鎖
    • 殺死行鎖進程

問題

最近使用golang做資金賬戶,目前涉及到這兩個問題

  • 資金入賬時,可能存在提現(xiàn)【出賬】
  • 資金提現(xiàn)時,可能存在資金入賬

因而,為了保證資金的正確性,這里需要事務操作。

什么是事務

MySQL 事務主要用于處理操作量大,復雜度高的數(shù)據(jù)。比如說,在人員管理系統(tǒng)中,你刪除一個人員,你既需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數(shù)據(jù)庫操作語句就構成一個事務!

為什么需要事務

以上面資金出賬和入賬為例子,寫出如下沒有事務的代碼:

創(chuàng)建賬戶表

mysql> create table account (-> id int(11) primary key not null auto_increment comment '賬戶自增主鍵id',-> userId int(11) not null comment '用戶id',-> balance int(11) not null DEFAULT 0 comment '賬戶余額,默認為0'-> ) ENGINE = 'INNODB'; Query OK, 0 rows affected (0.06 sec)

由Query OK, 0 rows affected (0.06 sec)可知,account表創(chuàng)建成功。

插入數(shù)據(jù)

mysql> insert into account(userId,balance) values(1223,444),(1224,666); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0

由Query OK, 2 rows affected (0.01 sec)可知,數(shù)據(jù)插入成功。

無事務資金出入賬

  • 假設用戶1223給用戶1224轉賬100元。
  • 若轉賬成功,用戶1223的賬戶余額為344元,用戶1224的賬戶余額為766元。
  • 如果轉賬失敗,用戶1223給用戶1224的賬戶余額不變。

按照這個想法,設計如下SQL語句,此時是沒有事務的:

-- 執(zhí)行用戶1223的出賬,用戶1224的入賬 mysql> update account set balance = balance -100 where userId = 1223;update account set balance = balance + 100 where useId = 1224 ;Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0ERROR 1054 (42S22): Unknown column 'useId' in 'where clause'

在兩條SQL語句中,用戶1223出賬SQL語句正確,即其賬戶余額為344元;用戶1224入賬SQL語句錯誤,因為account表中沒有useId這個字段,因而其賬戶余額不變,仍舊是666元,如下SQL所示:

mysql> select * from account; +----+--------+---------+ | id | userId | balance | +----+--------+---------+ | 1 | 1223 | 344 | | 2 | 1224 | 666 | +----+--------+---------+ 2 rows in set (0.00 sec)

這就和我們的預期不同,此時,我們使用如下SQL恢復用戶1223的賬戶余額:

mysql> update account set balance = balance + 100 where userId = 1223 ;Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0

然后使用事務,再次執(zhí)行上述SQL。

有事務資金出入賬

依舊是``用戶1223給用戶1224```轉賬100元,如下所示:

-- 開啟事務 mysql> begin; Query OK, 0 rows affected (0.00 sec)-- 執(zhí)行用戶1223的出賬,用戶1224的入賬 mysql> update account set balance = balance -100 where userId = 1223;update account set balance = balance + 100 where useId = 1224 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0ERROR 1054 (42S22): Unknown column 'useId' in 'where clause'-- 出現(xiàn)錯誤語句,回滾金額 mysql> rollback; Query OK, 0 rows affected (0.01 sec)-- 查詢回滾后的賬戶余額 mysql> select * from account; +----+--------+---------+ | id | userId | balance | +----+--------+---------+ | 1 | 1223 | 444 | | 2 | 1224 | 666 | +----+--------+---------+ 2 rows in set (0.00 sec)
  • 首先,開啟事務
  • 執(zhí)行用戶1223的出賬,用戶1224的入賬
  • 用戶1223的出賬SQL正確,用戶1224的入賬SQL錯誤
  • 出現(xiàn)錯誤的SQL語句,事務回滾
  • 查詢賬戶余額,發(fā)現(xiàn)賬戶余額不變,符合我們的預期。

因而,為了保證資金的正確性,我們必須使用事務。

事務死鎖

死鎖出現(xiàn)的原因

在事務的情況下,給某個賬戶加上行級鎖。

我使用的是for update的悲觀行級鎖,但前置條件是,當前賬戶要存在,否則,行級鎖就會變成表解鎖,鎖粒度就會增加。

比如,在提現(xiàn)時,需要判斷當前賬戶是否綁卡,如果沒有綁卡,就拋出您尚未綁卡的toast。一般情況下都綁了卡,但就怕特殊情況,真的是想啥來啥。恰巧遇到某用戶沒有綁卡,拋出您尚未綁卡的toast之后,再次訪問就報出如下問題:

于是去排查問題,發(fā)現(xiàn)在拋出尚未綁卡的異常時,沒有將事務回滾,于是,此處添加事務回滾tx.rollBack。

如果不進行事務回滾,那么當前行就不釋放鎖,相同的請求SQL過來,就會不停地嘗試連接,,如果連接不成功,則會拋出連接超時的問題。

當前行不釋放鎖,新的SQL請求加鎖,便出現(xiàn)了死鎖的情況。

解決事務死鎖

查看表級鎖

如果行級鎖不存在,使用SQLshow OPEN TABLES where In_use > 0查看是否存在表級鎖,如下SQL所示:

mysql> show OPEN TABLES where In_use > 0; Empty set (0.00 sec)

查詢表鎖進程

其次,查詢進程(如果您有SUPER權限,您可以看到所有線程。否則,您只能看到您自己的線程)show processlist,最后殺死【kill】進程id

查詢行級鎖

使用sql語句SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;查看當前存在鎖的事務,如下圖存在一個事務死鎖:

殺死行鎖進程

殺死鎖進程,我們可以使用命令: kill trx_mysql_thread_id

比如殺死如上的行級死鎖,找到trx_mysql_thread_id的數(shù)值,執(zhí)行命令:kill 4314823

總結

以上是生活随笔為你收集整理的mysql事务 mysql事务回滚 MySQL事务死锁 如何解除死锁 资金出入账的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。