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();
    }
}

  

posted @   yinghualeihenmei  阅读(155)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示