解讀SQL一些語句執(zhí)行后出現(xiàn)異常不會回滾的問題
SQL一些語句執(zhí)行后出現(xiàn)異常不會回滾
MySQL回滾問題
SQL中會隱式提交的操作:
1、DDL語句:ALTER DATABASE、ALTER EVENT、ALTER PROCEDURE、ALTER TABLE、ALTER VIEW、CREATE TABLE、DROP TABLE、RENAME TABLE、TRUNCATE TABLE等;
2、修改MYSQL架構(gòu)的語句:CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD;
3、管理語句:ANALYZE TABLE、CACHE INDEX、CHECK TABLE、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE等,
總結(jié):設計事務時,不應包含這類語句。如果在事務的前部中發(fā)布了一個不能被回滾的語句,則后部的其它語句會發(fā)生錯誤,在這些情況下,通過發(fā)布ROLLBACK語句不能 回滾事務的全部效果,簡單來說如果這個不
能被回滾的語句之前有事務,并且這個不能被回滾的語句執(zhí)行異常了,之前的修改操作會隱式的提交。
例如:
這種情況下 int i=5/0;發(fā)生異常了,上面的修改操作會發(fā)生回滾,修改密碼失敗的。

這種情況下userMapper.dropField(tableName,fieldName);我故意tableName傳一個不存在的表名,這里會拋出異常,但是上面的更新密碼操作還是會成功(隱式地提交了事務)

SQL事務回滾的兩種方式
1.XACT_ABORT
1)set XACT_ABORT off時,回滾產(chǎn)生錯誤的Transact-SQL語句,而事務將繼續(xù)進行處理,(注:錯誤嚴重或者語法錯誤時可能回滾整個事務)
2) set XACT_ABORT ON時,如果Transact-SQL語句產(chǎn)生運行時錯誤,整個事務將終止并回滾,
步驟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
--默認XACT_ABORT=off
SET XACT_ABORT off
begin tran
insert into [dbo].[A](Name,CreateDate) values('測試off',GETDATE());
insert into [dbo].[A](Name,CreateDate) values('測試off_異常',GETDATE());
insert into [dbo].[A](Name,CreateDate) values('測試off',GETDATE());
commit tran
(1 行受影響)
- 消息 8152,級別 16,狀態(tài) 4,第 3 行
- 將截斷字符串或二進制數(shù)據(jù)。
- 語句已終止。
(1 行受影響)
select * from [dbo].[A]
| ID | Name | CreateDate |
| 1 | 測試off | 2018-10-31 15:06:09.330 |
| 3 | 測試off | 2018-10-31 15:06:09.333 |
注意:
事務的回滾對于擁有自增主鍵的表來說,insert的數(shù)據(jù)是被刪除,update和delete的數(shù)據(jù)是被恢復 。所以上面所顯示的ID=3 。
步驟2:
set XACT_ABORT ON
begin tran
insert into [dbo].[A](Name,CreateDate) values('測試on',GETDATE());
insert into [dbo].[A](Name,CreateDate) values('測試on_異常',GETDATE());
insert into [dbo].[A](Name,CreateDate) values('測試on',GETDATE());
commit tran同樣執(zhí)行select 查詢語句 得到如下結(jié)果
| ID | Name | CreateDate |
| 1 | 測試off | 2018-10-31 15:06:09.330 |
| 3 | 測試off | 2018-10-31 15:06:09.333 |
證明事務全部回滾成功。(注意下次新增數(shù)據(jù)的時候,ID的值。。。)
2.rollback
在sql中用事務的時候一般是這么寫。
declare @error int ;
begin tran
begin try
insert into [dbo].[A](Name,CreateDate) values('測試異常',GETDATE());
insert into [dbo].[A](Name,CreateDate) values('測試異常_錯誤',GETDATE());
insert into [dbo].[A](Name,CreateDate) values('測試異常',GETDATE());
end try
begin catch
set @error=1
end catch
if @error>0
rollback tran
else
commit tran注:
判斷事務回滾,則整個事務里面的sql語句一起回滾,跟SET XACT_ABORT ON相似,不同的是當事務進行嵌套時,如果用事務判斷的方法,嵌套的子事務不出錯,外面語句出錯,那么整個事務只會回滾外面出錯的語句,子事務提交成功了就回滾不了了,但是用SET XACT_ABORT ON,即使子事務提交成功,如果外圍事務出錯,子事務還是回滾.
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
sqlserver實現(xiàn)樹形結(jié)構(gòu)遞歸查詢(無限極分類)的方法
下面小編就為大家?guī)硪黄猻qlserver實現(xiàn)樹形結(jié)構(gòu)遞歸查詢(無限極分類)的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07
使用phpMyAdmin修改MySQL數(shù)據(jù)庫root用戶密碼的方法
這篇文章主要介紹了使用phpMyAdmin修改MySQL數(shù)據(jù)庫root用戶密碼的方法,需要的朋友可以參考下2014-04-04
數(shù)據(jù)轉(zhuǎn)換沖突及轉(zhuǎn)換過程中大對象的處理
數(shù)據(jù)轉(zhuǎn)換沖突及轉(zhuǎn)換過程中大對象的處理方法,大家可以參考下。2009-07-07
將sqlserver數(shù)據(jù)遷移到mysql的詳細步驟記錄
這篇文章主要介紹了將SQL?Server數(shù)據(jù)遷移到MySQL的步驟,包括導出數(shù)據(jù)、轉(zhuǎn)換數(shù)據(jù)格式和導入數(shù)據(jù),通過示例和工具說明,幫助大家順利完成遷移任務,需要的朋友可以參考下2025-01-01
SqlServer2000+ 身份證合法校驗函數(shù)的示例代碼
這篇文章主要介紹了SqlServer2000+ 身份證合法校驗函數(shù),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05

