解讀SQL一些語(yǔ)句執(zhí)行后出現(xiàn)異常不會(huì)回滾的問(wèn)題
SQL一些語(yǔ)句執(zhí)行后出現(xiàn)異常不會(huì)回滾
MySQL回滾問(wèn)題
SQL中會(huì)隱式提交的操作:
1、DDL語(yǔ)句:ALTER DATABASE、ALTER EVENT、ALTER PROCEDURE、ALTER TABLE、ALTER VIEW、CREATE TABLE、DROP TABLE、RENAME TABLE、TRUNCATE TABLE等;
2、修改MYSQL架構(gòu)的語(yǔ)句:CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD;
3、管理語(yǔ)句:ANALYZE TABLE、CACHE INDEX、CHECK TABLE、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE等,
總結(jié):設(shè)計(jì)事務(wù)時(shí),不應(yīng)包含這類(lèi)語(yǔ)句。如果在事務(wù)的前部中發(fā)布了一個(gè)不能被回滾的語(yǔ)句,則后部的其它語(yǔ)句會(huì)發(fā)生錯(cuò)誤,在這些情況下,通過(guò)發(fā)布ROLLBACK語(yǔ)句不能 回滾事務(wù)的全部效果,簡(jiǎn)單來(lái)說(shuō)如果這個(gè)不
能被回滾的語(yǔ)句之前有事務(wù),并且這個(gè)不能被回滾的語(yǔ)句執(zhí)行異常了,之前的修改操作會(huì)隱式的提交。
例如:
這種情況下 int i=5/0;發(fā)生異常了,上面的修改操作會(huì)發(fā)生回滾,修改密碼失敗的。
這種情況下userMapper.dropField(tableName,fieldName);我故意tableName傳一個(gè)不存在的表名,這里會(huì)拋出異常,但是上面的更新密碼操作還是會(huì)成功(隱式地提交了事務(wù))
SQL事務(wù)回滾的兩種方式
1.XACT_ABORT
1)set XACT_ABORT off時(shí),回滾產(chǎn)生錯(cuò)誤的Transact-SQL語(yǔ)句,而事務(wù)將繼續(xù)進(jìn)行處理,(注:錯(cuò)誤嚴(yán)重或者語(yǔ)法錯(cuò)誤時(shí)可能回滾整個(gè)事務(wù))
2) set XACT_ABORT ON時(shí),如果Transact-SQL語(yǔ)句產(chǎn)生運(yùn)行時(shí)錯(cuò)誤,整個(gè)事務(wù)將終止并回滾,
步驟1:
CREATE TABLE [dbo].[A]( [ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL, [Name] [nvarchar](5) NULL, [CreateDate] [datetime] NULL, CONSTRAINT [PK_A] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO --默認(rèn)XACT_ABORT=off SET XACT_ABORT off begin tran insert into [dbo].[A](Name,CreateDate) values('測(cè)試off',GETDATE()); insert into [dbo].[A](Name,CreateDate) values('測(cè)試off_異常',GETDATE()); insert into [dbo].[A](Name,CreateDate) values('測(cè)試off',GETDATE()); commit tran
(1 行受影響)
- 消息 8152,級(jí)別 16,狀態(tài) 4,第 3 行
- 將截?cái)嘧址蚨M(jìn)制數(shù)據(jù)。
- 語(yǔ)句已終止。
(1 行受影響)
select * from [dbo].[A]
ID | Name | CreateDate |
1 | 測(cè)試off | 2018-10-31 15:06:09.330 |
3 | 測(cè)試off | 2018-10-31 15:06:09.333 |
注意:
事務(wù)的回滾對(duì)于擁有自增主鍵的表來(lái)說(shuō),insert的數(shù)據(jù)是被刪除,update和delete的數(shù)據(jù)是被恢復(fù) 。所以上面所顯示的ID=3 。
步驟2:
set XACT_ABORT ON begin tran insert into [dbo].[A](Name,CreateDate) values('測(cè)試on',GETDATE()); insert into [dbo].[A](Name,CreateDate) values('測(cè)試on_異常',GETDATE()); insert into [dbo].[A](Name,CreateDate) values('測(cè)試on',GETDATE()); commit tran
同樣執(zhí)行select 查詢(xún)語(yǔ)句 得到如下結(jié)果
ID | Name | CreateDate |
1 | 測(cè)試off | 2018-10-31 15:06:09.330 |
3 | 測(cè)試off | 2018-10-31 15:06:09.333 |
證明事務(wù)全部回滾成功。(注意下次新增數(shù)據(jù)的時(shí)候,ID的值。。。)
2.rollback
在sql中用事務(wù)的時(shí)候一般是這么寫(xiě)。
declare @error int ; begin tran begin try insert into [dbo].[A](Name,CreateDate) values('測(cè)試異常',GETDATE()); insert into [dbo].[A](Name,CreateDate) values('測(cè)試異常_錯(cuò)誤',GETDATE()); insert into [dbo].[A](Name,CreateDate) values('測(cè)試異常',GETDATE()); end try begin catch set @error=1 end catch if @error>0 rollback tran else commit tran
注:
判斷事務(wù)回滾,則整個(gè)事務(wù)里面的sql語(yǔ)句一起回滾,跟SET XACT_ABORT ON相似,不同的是當(dāng)事務(wù)進(jìn)行嵌套時(shí),如果用事務(wù)判斷的方法,嵌套的子事務(wù)不出錯(cuò),外面語(yǔ)句出錯(cuò),那么整個(gè)事務(wù)只會(huì)回滾外面出錯(cuò)的語(yǔ)句,子事務(wù)提交成功了就回滾不了了,但是用SET XACT_ABORT ON,即使子事務(wù)提交成功,如果外圍事務(wù)出錯(cuò),子事務(wù)還是回滾.
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
對(duì)有自增長(zhǎng)字段的表導(dǎo)入數(shù)據(jù)注意事項(xiàng)
對(duì)有自增長(zhǎng)字段的表導(dǎo)入數(shù)據(jù)注意事項(xiàng)2008-12-12sqlserver中關(guān)于WINDOWS性能計(jì)數(shù)器的介紹
sqlserver中關(guān)于WINDOWS 性能計(jì)數(shù)器的介紹,需要的朋友可以看下2013-01-01sql查詢(xún)表中根據(jù)某列排序的任意行語(yǔ)句
這篇文章主要介紹了sql查詢(xún)表中根據(jù)某列排序的任意行,需要的朋友可以參考下2014-03-03SQL Server 2000/2005/2008刪除或壓縮數(shù)據(jù)庫(kù)日志的方法
最近win2008 r2的服務(wù)器比較卡,打開(kāi)服務(wù)器顯示也特別慢,sqlserver業(yè)務(wù)費(fèi)正常執(zhí)行,服務(wù)器桌面操作也比較卡,經(jīng)過(guò)多方研究發(fā)現(xiàn)原來(lái)是sqlserver日志文件已經(jīng)達(dá)到了84G導(dǎo)致,這里就為大家分享一下解決方法,需要的朋友可以參考一下2019-09-09SQL Server如何通過(guò)創(chuàng)建臨時(shí)表遍歷更新數(shù)據(jù)詳解
這篇文章主要給大家介紹了關(guān)于SQL Server如何通過(guò)創(chuàng)建臨時(shí)表遍歷更新數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09SQLServer 數(shù)據(jù)庫(kù)故障修復(fù)頂級(jí)技巧之一
SQL Server 2005 和 2008 有幾個(gè)關(guān)于高可用性的選項(xiàng),如日志傳輸、副本和數(shù)據(jù)庫(kù)鏡像。2010-04-04SQL Server服務(wù)啟動(dòng)的實(shí)現(xiàn)步驟
本文主要介紹了SQL Server服務(wù)啟動(dòng)的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07