T - SQL使用事务 及 在Winform使用事务

事务适用场景

1 事务使用在存储过程中,直接在数据库中进行编写

2 事务使用在Winfrom项目中

SQl:使用事务转账操作的实例

一般都会找一个变量记录错误的个数,@error记录上一句sql的错误和错误编号

sql 复制代码
declare @errornum int  = 0 -- 定义一个记录错误个数的变量
begin transaction -- 开启事务
	begin
		-- 转出操作
		update Card set CurrentMoney = CurrentMoney - 100000 where StudentId = 1002
		set @errornum = @errornum + @@error -- 把@@error加到总的记录上
		-- 转入操作
		update Card set CurrentMoney = CurrentMoney + 100000 where StudentId = 1004
		set @errornum = @errornum + @@ERROR
		if(@errornum > 0) -- 证明有错误,把之前已经执行的操作回滚到原先的数据上
			rollback transaction -- 回滚事务
		else -- 没有错误,提交事务
			commit transaction
	end
go
select * from Card

声明一个过程 包含三个输入参数 分别是两个转账的卡号 和转账的金额

sql 复制代码
use YinHangDB
go
create procedure tt10000
	@outZhangHao int,
	@ruZhangHao int,
	@Money int
as
	declare @c1 int = 0--错误的个数
	begin transaction --开启事务
		begin
			--转出
			update Card set CurrentMoney = CurrentMoney - @Money where StudentId = @outZhangHao
			set @c1 = @c1 + @@ERROR

			--转入
			update Card set CurrentMoney = CurrentMoney + @Money where StudentId = @ruZhangHao
			set @c1 = @c1 + @@ERROR
			if(@c1>0)
				rollback transaction
			else 
				commit transaction
		end

go	
select * from Card
--测试转账失败的操作
exec tt10000 1000,1001,100000

--测试转账成功
exec tt10000 1000,1001,50000

Winfrom 使用事故实例

链接SQl 数据库

public string connString = @"Server=.;Database=SMDB;Uid=sa;Pwd=123456";

搭建Winfrom界面

测试事务回滚的方法

cs 复制代码
 private void button1_Click(object sender, EventArgs e)
 {
     //删除前学生总个数
     int num1 = (int)GetSingleCount("select count(*) from Students");
     this.listBox1.Items.Add("删除前学生总个数:"+ num1);  // 展示在listbox下


     // 测试删除学生失败进行事务回滚操作

     //定义一个列表字符串 
     List<string> list = new List<string>()
     {
       "delete from Students where StudentId = 1000005",
       "delete from Students where StudentId = 1000024",
       "delete from Students where StudentId = 1000006"
     };

     //执行删除操作 把list里面每一句sql都去执行一下

     int result = 0;
     try
     {
         result = UpdateDataBase(list);
     }
     catch (Exception ex)
     {

         this.listBox1.Items.Add(ex.Message);
     }

     if (result > 0)
     {
         this.listBox1.Items.Add("删除成功");
     }
     else
     {
         this.listBox1.Items.Add("删除失败");
     }
     this.listBox1.Items.Add("删除之后剩余人数为:" + (int)GetSingleCount("select count(*) from Students"));

 }

封装多个删除语句执行操作

参数是多个sql的集合

返回值 int是否执行成功

cs 复制代码
public int UpdateDataBase(List<string> list)
{
    SqlConnection conn = new SqlConnection(connString);
    //  new SqlCommand(sql, conn)
    //  没有指定执行sql 没有指定连接,下面必须在写代码把连接对象添加上
    SqlCommand cmd = new SqlCommand(); 
    cmd.Connection = conn;
    try
    {
        conn.Open();
        //开启事务
        cmd.Transaction = conn.BeginTransaction();
        int result = 0;//记录删除时候受影响的行数
        //取出每一个sql语句 分别执行
        foreach (string sql in list)
        {
            //设置执行的sql
            cmd.CommandText = sql; 
            result += cmd.ExecuteNonQuery();
         // cmd.ExecuteNonQuery() 返回受影响行数如果删除成功了,受影响行数不为0
        }
        //如果执行错误了 跳转到catch里面 在catch执行回滚
        // 没有出错 提交事务
        cmd.Transaction.Commit();
        return result;
    }
    catch(Exception ex)
    {
        if (cmd.Transaction != null)
        {
            cmd.Transaction.Rollback(); // 执行sql语句有错误的情况 执行回滚操作
        }
        throw new Exception("执行删除sql事务出错:" + ex.Message);
    }
    finally
    {
        // 不管是否执行有误 把事务置为null 清除事务
        if(cmd.Transaction!=null)
        {
            cmd.Transaction = null;
        }
        conn.Close();
    }
}

获取数据库个数的方法

public object GetSingleCount(string sql)

{

SqlConnection conn = new SqlConnection(connString);

SqlCommand cmd = new SqlCommand(sql, conn);

conn.Open();

return cmd.ExecuteScalar();

}

测试事务提交的方法

cs 复制代码
private void button2_Click(object sender, EventArgs e)
{
    //删除前学生总个数
    int num1 = (int)GetSingleCount("select count(*) from Students");
    this.listBox1.Items.Add("删除前学生总个数:" + num1);  // 展示在listbox下


    // 测试删除学生失败进行事务回滚操作

    //定义一个列表字符串 
    List<string> list = new List<string>()
    {
      "delete from Students where StudentId = 1000033",
      "delete from Students where StudentId = 1000031",
      "delete from Students where StudentId = 1000032"
    };

    //执行删除操作 把list里面每一句sql都去执行一下

    int result = 0;
    try
    {
        result = UpdateDataBase(list);
    }
    catch (Exception ex)
    {

        this.listBox1.Items.Add(ex.Message);
    }

    if (result > 0)
    {
        this.listBox1.Items.Add("删除成功");
    }
    else
    {
        this.listBox1.Items.Add("删除失败");
    }
    this.listBox1.Items.Add("删除之后剩余人数为:" + (int)GetSingleCount("select count(*) from Students"));
}
相关推荐
Qter_Sean33 分钟前
自己动手写Qt Creator插件
开发语言·qt
何曾参静谧37 分钟前
「QT」文件类 之 QIODevice 输入输出设备类
开发语言·qt
PGCCC38 分钟前
【PGCCC】Postgresql 存储设计
数据库·postgresql
爱吃生蚝的于勒2 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
PcVue China3 小时前
PcVue + SQL Grid : 释放数据的无限潜力
大数据·服务器·数据库·sql·科技·安全·oracle
小白学大数据4 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
魔道不误砍柴功5 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
冰芒猓5 小时前
SpringMVC数据校验、数据格式化处理、国际化设置
开发语言·maven
失落的香蕉5 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
锐策5 小时前
〔 MySQL 〕数据库基础
数据库·mysql