C#异常处理使用,ADO.NET启用事务,事务在开发中的一些用法

版权声明:Copyright:@@个人所有 https://blog.csdn.net/y20_20/article/details/90744676

目录

一、异常处理
二、程序中事务的一些用法介绍

一、异常的介绍和使用

1、异常的形式: 为了保证程序不会因为操作出现问题导致程序崩溃,需要添加异常。不处理异常会导致程序崩溃(CLR给出的 提示)

  • try中写上可能会 发生异常错误的代码;程序本身会把发生异常错误的类型自动生成一个异常对象类
  • catch中是捕获的异常,并处理异常,也可以写入日志(抛出和封装异常再抛出)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace exeception1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
            
                int n = Convert.ToInt32(Console.ReadLine());	//产生异常的语句 (输入123cuowu)
                Console.WriteLine("n转化为int类型后为:"+n);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);//输出产生的异常信息
            }
            Console.ReadKey();
        }
    }
}

2、异常处理的结构:

多路异常捕获:
try
{
会发生异常的代码都放在这里
}
catch(SqlException ex)//异常子类
{
SQLserver数据库异常信息;
//比如SQLserver数据库删除数据时,外键引用导致的错误 ,错误代码547
}
catch(Exception ex)//异常父类
{
SqlException异常没有捕获的异常,在这里一定能捕获
}
finally
{
不管有没有异常都会执行的代码都放在这里
}

3、对异常的处理方式:

  1. 立即处理: 产生异常后,给出提示或者处理其他逻辑使程序正常运行
  2. 抛出异常:对于复杂的程序,需要抛给上一层处理,也可以对异常进行封装后再抛出

二、程序中事务的一些使用介绍

在数据库端直接编写在存储过程内使用
1、为什么要使用事务: 执行多条增删改操作,保证要么都执行成功,要么都不执行

2、在程序端传输多条SQL语句的事务使用

两条一样的SQL语句:
 sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('山运维','男','1998-07-21',23,'852074196385201234',2)");
            sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('山运维','男','1998-07-21',23,'852074196385201234',2)");
运行结果:

其它异常信息:违反了 UNIQUE KEY 约束“uq_StudentIdNo”。不能在对象“dbo.Students”中插入重复键。重复键值为 (852074196385201234)。
语句已终止。            

执行成功的事务:要么都成功,要么都失败

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//引入操作数据库所需要的命名空间
using System.Data;
using System.Data.SqlClient;

namespace text2
{
    class Program
    {

        private static readonly string connString = @"Server=CHINA-20181227Q\server;DataBase=SMDB;User Id = sa; Password=123456";
        static void Main(string[] args)
        {
            InsertByTransaction();
            Console.ReadKey();
        }

        //通过传递SQL语句执行事务
        public static void InsertByTransaction()
        {
            List<string> sqlList = new List<string>();
            sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('山运维','男','1998-07-21',23,'852074196385201236',2)");
            sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('张建坤','男','1998-07-21',23,'852074196385201235',2)");

            try
            {
                Console.WriteLine(Update(sqlList));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
     
        /// <summary>
        /// 执行增删改的数据操作方法
        /// </summary>
        /// <param name="sql">SQL语句集合</param>
        /// <returns>返回受影响的行数</returns>
        public static int Update(List<string> sqlList)
        {
            SqlConnection conn = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            int count = 0;
            try
            {
                conn.Open();
                cmd.Transaction = conn.BeginTransaction();//开启数据库事务
                foreach (var sql in sqlList)
                {
                    cmd.CommandText = sql;
                    count+= cmd.ExecuteNonQuery();
                }
                cmd.Transaction.Commit();//提交事务
                return count;//返回受影响的行数
            }
            catch (SqlException ex)
            {
                if (cmd.Transaction!=null)
                {
                    cmd.Transaction.Rollback();//回滚事务(一旦多条SQL语句有一句错误,其余都不执行,回到执行前的状态)
                }
                if (ex.Number == 547)
                {
                    throw new Exception("被操作的数据有外键约束,请删除外键约束后再试!详细信息:" + ex.Message);
                }
                throw new Exception("其它异常信息:" + ex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception("操作 异常,请联系管理员!详细信息见:" + ex.Message);
            }
            finally
            {
                conn.Close();
            }
        }
	}
}

结果:2

3、多次调用同一个存储过程的事务
数据库端的存储过程:

USE [SMDB]
GO
/****** Object:  StoredProcedure [dbo].[usp_InsertStudent]    Script Date: 2019/6/2 星期日 22:45:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[usp_InsertStudent]
--存储过程参数
	@studentName varchar(20),
	@gender char(2),
	@birthday smalldatetime,
	@age int,
	@studentidno numeric(18,0),
	@classid int
as
	insert into Students(studentName,gender,birthday,age,studentidno,classid)
	 values(@studentName,@gender,@birthday,@age,@studentidno,@classid)

应用程序端掉用存储过程:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//引入操作数据库所需要的命名空间
using System.Data;
using System.Data.SqlClient;

namespace text2
{
    class Program
    {

        private static readonly string connString = @"Server=CHINA-20181227Q\server;DataBase=SMDB;User Id = sa; Password=123456";
        static void Main(string[] args)
        {
            InsertByTransaction();
            Console.ReadKey();
        }

        //通过传递SQL语句执行事务
        public static void InsertByTransaction()
        {

            //要添加的数据(可以是表单获取的,也可以是窗体控件获取的)
            //string studentName = "山运维";//参数不能为空,并且不能出现多参数和少参数的情况
            //string gender = "男";
            //DateTime birthday = Convert.ToDateTime("1998-07-21");
            //int age = 18;
            //string studentidno = "852074196385201234";
            //int classid = 2;

            SqlParameter[] param1 = new SqlParameter[] 
            {
                new SqlParameter("@studentname","山运维"),
                new SqlParameter("@gender","男"),
                new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
                new SqlParameter("@age",18),
                new SqlParameter("@studentidno","852074196385201234"),
                new SqlParameter("@classid",2)
            };

            SqlParameter[] param2 = new SqlParameter[]
            {
                new SqlParameter("@studentname","张建坤"),
                new SqlParameter("@gender","男"),
                new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
                new SqlParameter("@age",18),
                new SqlParameter("@studentidno","852074196385201235"),
                new SqlParameter("@classid",2)
            };
            List<SqlParameter[]> paramList = new List<SqlParameter[]>();
            paramList.Add(param1);
            paramList.Add(param2);
            try
            {
                Console.WriteLine(Update("usp_InsertStudent",paramList));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 反复调用同一个存储过程
        /// </summary>
        /// <param name="procedureName"></param>
        /// <param name="paramList"></param>
        /// <returns></returns>
        public static int Update(string procedureName, List<SqlParameter[]> paramList)
        {
            SqlConnection conn = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand(procedureName,conn);
            cmd.CommandType= CommandType.StoredProcedure;
            int count = 0;
            try
            {
                conn.Open();
                cmd.Transaction = conn.BeginTransaction();//开启数据库事务
                foreach (var param in paramList)
                {
                    cmd.Parameters.Clear();//清空参数
                    cmd.Parameters.AddRange(param);
                    count+= cmd.ExecuteNonQuery();
                }
                cmd.Transaction.Commit();//提交事务
                return count;//返回受影响的行数
            }
            catch (SqlException ex)
            {
                if (cmd.Transaction!=null)
                {
                    cmd.Transaction.Rollback();//回滚事务(一旦多条SQL语句有一句错误,其余都不执行,回到执行前的状态)
                }
                if (ex.Number == 547)
                {
                    throw new Exception("被操作的数据有外键约束,请删除外键约束后再试!详细信息:" + ex.Message);
                }
                throw new Exception("其它异常信息:" + ex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception("操作 异常,请联系管理员!详细信息见:" + ex.Message);
            }
            finally
            {
                conn.Close();
            }
        }
    }
}

执行成功返回结果:2

4、多次调用不同的存储过程的事务
数据库端的存储过程创建:

存储过程一:
create procedure [dbo].[usp_InsertStudent1]
--存储过程参数
	@studentName varchar(20),
	@gender char(2),
	@birthday smalldatetime,
	@age int,
	@studentidno numeric(18,0),
	@classid int
as
	insert into Students(studentName,gender,birthday,age,studentidno,classid)
	 values(@studentName,@gender,@birthday,@age,@studentidno,@classid)


存储过程二:
create procedure [dbo].[usp_InsertStudent]
--存储过程参数
	@studentName varchar(20),
	@gender char(2),
	@birthday smalldatetime,
	@age int,
	@studentidno numeric(18,0),
	@classid int
as
	insert into Students(studentName,gender,birthday,age,studentidno,classid)
	 values(@studentName,@gender,@birthday,@age,@studentidno,@classid)

VS代码测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//引入操作数据库所需要的命名空间
using System.Data;
using System.Data.SqlClient;

namespace text2
{
    class Program
    {

        private static readonly string connString = @"Server=CHINA-20181227Q\server;DataBase=SMDB;User Id = sa; Password=123456";
        static void Main(string[] args)
        {
            InsertByTransaction();
            Console.ReadKey();
        }

        //通过传递SQL语句执行事务
        public static void InsertByTransaction()
        {

            //要添加的数据(可以是表单获取的,也可以是窗体控件获取的)
            //string studentName = "山运维";//参数不能为空,并且不能出现多参数和少参数的情况
            //string gender = "男";
            //DateTime birthday = Convert.ToDateTime("1998-07-21");
            //int age = 18;
            //string studentidno = "852074196385201234";
            //int classid = 2;

            SqlParameter[] param1 = new SqlParameter[] 
            {
                new SqlParameter("@studentname","山运维"),
                new SqlParameter("@gender","男"),
                new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
                new SqlParameter("@age",18),
                new SqlParameter("@studentidno","852074196385201234"),
                new SqlParameter("@classid",2)
            };

            SqlParameter[] param2 = new SqlParameter[]
            {
                new SqlParameter("@studentname","张建坤"),
                new SqlParameter("@gender","男"),
                new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
                new SqlParameter("@age",18),
                new SqlParameter("@studentidno","852074196385201235"),
                new SqlParameter("@classid",2)
            };

            Dictionary<string, SqlParameter[]> paramAndprocedure = new Dictionary<string, SqlParameter[]>();
            paramAndprocedure.Add("usp_InsertStudent1",param1);
            paramAndprocedure.Add("usp_InsertStudent", param2);
            try
            {
                Console.WriteLine(Update(paramAndprocedure));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

       
        public static int Update(Dictionary<string ,SqlParameter[]> paramAndprocedure)
        {
            SqlConnection conn = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandType= CommandType.StoredProcedure;
            int count = 0;
            try
            {
                conn.Open();
                cmd.Transaction = conn.BeginTransaction();//开启数据库事务
                foreach (var procedureName in paramAndprocedure.Keys)
                {
                    cmd.CommandText = procedureName;
                    if (paramAndprocedure[procedureName].Length > 0)//判断是否有参数
                    {
                        cmd.Parameters.Clear();//清空参数
                        cmd.Parameters.AddRange(paramAndprocedure[procedureName]);
                    }
                    count+= cmd.ExecuteNonQuery();
                }
                cmd.Transaction.Commit();//提交事务
                return count;//返回受影响的行数
            }
            catch (SqlException ex)
            {
                if (cmd.Transaction!=null)
                {
                    cmd.Transaction.Rollback();//回滚事务(一旦多条SQL语句有一句错误,其余都不执行,回到执行前的状态)
                }
                if (ex.Number == 547)
                {
                    throw new Exception("被操作的数据有外键约束,请删除外键约束后再试!详细信息:" + ex.Message);
                }
                throw new Exception("其它异常信息:" + ex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception("操作 异常,请联系管理员!详细信息见:" + ex.Message);
            }
            finally
            {
                conn.Close();
            }
        }
    }
}

执行成功测试结果:返回2

猜你喜欢

转载自blog.csdn.net/y20_20/article/details/90744676