SqlServer事务语法及使用方法
原文链接:https://blog.csdn.net/xiaouncle/article/details/52891563
事务是关于原子性的。原子性的概念是指可以把一些事情当做一个不可分割的单元来看待。从数据库的角度看,它是指应全部执行或全部不执行的一条或多条语句的最小组合。
可以使用一些T-SQL语句在事务中“标记”这些点。
begin tran:设置起点
commit tran:使事务成为数据库中永久的、不可逆转的一部分
rollback tran:本质上说想要忘记它曾经发生过
save tran:创建一个特定标记,只允许部分回滚
SqlServer事务实例
事务代码1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | begin tran tran_AddUserInfo --开始事务 declare @tran_error int ; set @tran_error=0; begin try insert into dbo.UserInfo values (2016009, 'aaa' , '2016-08-19 09:13:41.227' , '男' ) insert into dbo.UserInfo values (2016009, 'bbb' , '2016-08-19 09:13:41.227' , '哼哼哼' ) insert into dbo.UserInfo values (2016009, 'ccc' , '2016-08-19 09:13:41.227' , '哈哈哈' ) end try begin catch set @tran_error=@tran_error+1; --加分号或不加都能正常执行 end catch if(@tran_error>0) begin rollback tran tran_AddUserInfo; --执行出错,回滚事务(指定事务名称) print @tran_error; end else begin commit tran tran_AddUserInfo; --没有异常,提交事务(指定事务名称) print @tran_error; end |
事务代码2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | begin tran tran_AddUserInfo --开始事务 declare @tran_error int ; set @tran_error=0; begin try insert into dbo.UserInfo values (2016009, 'aaa' , '2016-08-19 09:13:41.227' , '男' ) insert into dbo.UserInfo values (2016009, 'bbb' , '2016-08-19 09:13:41.227' , '哈哈' ) insert into dbo.UserInfo values (2016009, 'ccc' , '2016-08-19 09:13:41.227' , '哈哈' ) end try begin catch set @tran_error=@tran_error+1; --加分号或不加都能正常执行 end catch if(@tran_error>0) begin rollback tran; --执行出错,回滚事务(不指定事务名称) print @tran_error; end else begin commit tran; --没有异常,提交事务(不指定事务名称) print @tran_error; end |
SqlServer记录异常信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ALTER PROCEDURE [dbo].[proc_SysRole] -- Add the parameters for the stored procedure here @RoleCode varchar (50), @RoleName nvarchar(50), @RoleValue nvarchar(100), @ParentCode varchar (50), @IsActive int AS declare @clientId varchar (20); BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON ; -- Insert statements for procedure here begin tran begin try insert into Sys_Role(RoleCode, RoleName, RoleValue, ParentCode, IsActive) values (@RoleCode, @RoleName, @RoleValue, @ParentCode, @IsActive) end try begin catch if(@@TRANCOUNT>0) begin rollback tran --获取执行者所在服务器的ip select @clientId=client_net_address from sys.dm_exec_connections where Session_id=@@spid --记录异常信息 insert into Sys_ProcLog(ClientId, ProcName, ErrorInfo, CreateDate) values (@clientId,ERROR_PROCEDURE(),ERROR_MESSAGE(),GETDATE()) end end catch if(@@TRANCOUNT>0) begin commit tran end END |
SqlServer无法捕获的异常需要特殊处理
将无法正常捕获异常的T-SQL语句转换成字符串,然后利用exec()执行,就能捕捉到异常了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | begin tran tran1 begin try TRUNCATE TABLE dbo.Sync_App_Gululu --查询Oracle数据库的链接服务器 exec ( 'INSERT INTO dbo.Sync_App_Gululu SELECT *,GETDATE() AS SyncTime FROM OPENQUERY(SSO_Forumn,' 'select * from dbo.UserInfo' ')' ) end try begin catch set @tranError=@tranError+1; print 'catch:' +str(@tranError); end catch if(@tranError>0) begin rollback tran tran1; print 'rollback tran:' +str(@tranError); end else begin commit tran tran1; print 'commit tran:' +str(@tranError); end |
C#后台代码拼Sql事务语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public partial class TestSqlTran : System.Web.UI.Page { protected void Page_Load( object sender, EventArgs e) { if (!IsPostBack) { Execute(); } } private void Execute() { string connString = ConfigurationManager.ConnectionStrings[ "connString" ].ToString(); SqlConnection connection = new SqlConnection(connString); StringBuilder sqlSB= new StringBuilder(); /*sqlSB.AppendLine("begin tran tran_handle")与SqlServer中的换行不是一回事, C#后台每行Sql语句后边必须加空格分隔, 不能用sqlSB.AppendLine("begin tran tran_handle")来替代sqlSB.Append("begin tran tran_handle ") */ sqlSB.Append( "begin tran tran_handle " ); sqlSB.AppendFormat( "declare {0} int;set {0}=0;" , "@tran_error" ); sqlSB.Append( "begin try " ); sqlSB.AppendFormat( "delete from Descriptions where Id='{0}' " , "1" ); sqlSB.Append( "end try " ); sqlSB.Append( "begin catch " ); //set @tran_error=@tran_error+1;以分号结尾可以不用空格 sqlSB.Append( "set @tran_error=@tran_error+1;" ); sqlSB.Append( "end catch " ); sqlSB.Append( "if(@tran_error>0) begin rollback tran; end " ); sqlSB.Append( "else begin commit tran; end " ); SqlCommand cmd= new SqlCommand(sqlSB.ToString(),connection); connection.Open(); int count = cmd.ExecuteNonQuery(); connection.Close(); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了