C#事务处理(二)之ADO.NET事务

在发布System.Transaction名称之前,可以使用ADO.NET创建事务,也可以通过组件,特性和COM+(位于System.EnterpriseServices)运行库进行事务处理。

1.ADO.NET事务

首先看看传统的ADO.NET事务,如果没有手动创建事务,每条SQL语句就都有一个事务。如果多条语句应参与到一个事务处理中,就必须手动创建一个事务。

下面的代码是说明如何使用ADO.NET事务。SqlConnection类定义了BeginTransaction方法,它返回一个SqlTransation类型的对象。这个事务对象必须参与事务处理的每条命令关联起来。要把命令关联到事务处理上,可将SqlCommand类的Transaction属性设置SqlTransaction实例,为了使事务成功完成,必须调用Commit方法。如果有错误,就必须调用RollBack方法,并撤销每个修改。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;

namespace DataAccess
{
    /// <summary>
    /// DBHelper对SQL数据库进行操作
    /// </summary>
    /// DBHelper定义为抽象类,不允许实例化
    public abstract class DBHelper
    {
        #region 获取数据库连接的地址

        private static string _ConnStr;

        /// <summary>
        /// 在Web.config中设定一条connectionStrings
        /// </summary>
        public static string ConnString
        {
            set { _ConnStr = value; }
        }

        #endregion 获取数据库连接的地址

        #region 对数据库进行 增、删、改 操作

        public static int ExecuteNonQuery(string sql)
        {
            return ExecuteNonQuery(sql, CommandType.Text, null);
        }

        public static int ExecuteNonQuery(string sql, SqlParameter[] sqlParams)
        {
            return ExecuteNonQuery(sql, CommandType.Text, sqlParams);
        }

        /// <summary>
        /// ExecuteNonQuery操作,对数据库进行 增、删、改 操作
        /// <para>返回受影响的行数,返回-1表示数据库操作失败</para>
        /// </summary>
        /// <param name="sql">要执行的SQL语句 </param>
        /// <param name="commandType">要执行的查询类型(存储过程、SQL文本) </param>
        /// <param name="parameters">参数数组 </param>
        /// <returns>返回受影响的行数,返回-1表示数据库操作失败</returns>
        public static int ExecuteNonQuery(string sql, CommandType commandType, SqlParameter[] sqlParams)
        {
            int count = 0;
            using (SqlConnection sqlConn = new SqlConnection(_ConnStr))
            {
                using (SqlCommand sqlComm = new SqlCommand(sql, sqlConn))
                {
                    sqlComm.CommandType = commandType;
                    if (sqlParams != null)
                    {
                        foreach (SqlParameter sqlParam in sqlParams)
                        {
                            sqlComm.Parameters.Add(sqlParam);
                        }
                    }

                    try
                    {
                        sqlConn.Open();
                        count = sqlComm.ExecuteNonQuery();
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }
            return count;
        }

        #endregion 对数据库进行 增、删、改 操作

        #region 查询并返回一个DataSet类型结果

        public static DataSet ExecuteDataSet(string sql)
        {
            return ExecuteDataSet(sql, CommandType.Text, null);
        }

        public static DataSet ExecuteDataSet(string sql, SqlParameter[] parameters)
        {
            return ExecuteDataSet(sql, CommandType.Text, parameters);
        }

        /// <summary>
        /// SqlDataAdapter的Fill方法执行一个查询,并返回一个DataSet类型结果
        /// <para>返回一个DataSet对象,如果无法连接数据库或查询的结果为空,则返回null</para>
        /// </summary>
        /// <param name="sql">要执行的SQL语句 </param>
        /// <param name="commandType">要执行的查询类型(存储过程、SQL文本) </param>
        /// <param name="parameters">参数数组 </param>
        /// <returns>返回一个DataSet对象,如果无法连接数据库或查询的结果为空,则返回null</returns>
        public static DataSet ExecuteDataSet(string sql, CommandType commandType, SqlParameter[] parameters)
        {
            DataSet ds = new DataSet();
            using (SqlConnection connection = new SqlConnection(_ConnStr))
            {
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    command.CommandType = commandType;
                    command.CommandTimeout = 120;
                    if (parameters != null)
                    {
                        foreach (SqlParameter parameter in parameters)
                        {
                            command.Parameters.Add(parameter);
                        }
                    }

                    try
                    {
                        SqlDataAdapter adapter = new SqlDataAdapter(command);
                        adapter.Fill(ds);
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }
            return ds;
        }

        #endregion 查询并返回一个DataSet类型结果

        #region 查询并返回一个DataTabel类型结果

        public static DataTable ExecuteDataTable(string sql)
        {
            return ExecuteDataTable(sql, CommandType.Text, null);
        }

        public static DataTable ExecuteDataTable(string sql, SqlParameter[] parameters)
        {
            return ExecuteDataTable(sql, CommandType.Text, parameters);
        }

        public static DataTable ExecuteDataTable(string sql, CommandType commandType)
        {
            return ExecuteDataTable(sql, commandType, null);
        }

        /// <summary>
        /// SqlDataAdapter的Fill方法执行一个查询,并返回一个DataTable类型结果
        /// <para>返回一个DataTabel对象,如果无法连接数据库或查询的结果为空,则返回null</para>
        /// </summary>
        /// <param name="sql">要执行的SQL语句 </param>
        /// <param name="commandType">要执行的查询类型(存储过程、SQL文本) </param>
        /// <param name="parameters">参数数组 </param>
        /// <returns>返回一个DataTabel对象,如果无法连接数据库或查询的结果为空,则返回null</returns>
        public static DataTable ExecuteDataTable(string sql, CommandType commandType, SqlParameter[] parameters)
        {
            DataTable dt = new DataTable();
            using (SqlConnection connection = new SqlConnection(_ConnStr))
            {
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    command.CommandType = commandType;
                    if (parameters != null)
                    {
                        foreach (SqlParameter parameter in parameters)
                        {
                            command.Parameters.Add(parameter);
                        }
                    }

                    try
                    {
                        SqlDataAdapter adapter = new SqlDataAdapter(command);
                        adapter.Fill(dt);
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }
            return dt;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="sql">要执行的SQL语句</param>
        /// <param name="sqlCount">查询满足条件的总行数SQL语句</param>
        /// <param name="parameters">参数数组</param>
        /// <param name="totalCount">传递总行数</param>
        /// <returns></returns>
        public static DataTable ExecuteDataTable(string sql, string sqlCount, SqlParameter[] parameters, ref int totalCount)
        {
            DataSet ds = new DataSet();
            using (SqlConnection connection = new SqlConnection(_ConnStr))
            {
                using (SqlCommand command = new SqlCommand(sql + ";" + sqlCount, connection))
                {
                    command.CommandType = CommandType.Text;
                    if (parameters != null)
                    {
                        foreach (SqlParameter parameter in parameters)
                        {
                            command.Parameters.Add(parameter);
                        }
                    }

                    try
                    {
                        SqlDataAdapter adapter = new SqlDataAdapter(command);
                        adapter.Fill(ds);

                        if (ds.Tables.Count == 2 && ds.Tables[1] != null && ds.Tables[1].Rows.Count > 0)
                        {
                            totalCount = (int)ds.Tables[1].Rows[0][0];
                        }
                        else
                        {
                            totalCount = 0;
                        }
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }

            if (ds != null && ds.Tables.Count > 0)
            {
                return ds.Tables[0];
            }
            else
            {
                throw new Exception("Failed to query to meet the conditions of the collection!");
            }
        }

        #endregion 查询并返回一个DataTabel类型结果

        #region 查询并返回一个SqlDataReader对象实例

        /// <summary>
        /// ExecuteReader执行一查询,返回一SqlDataReader对象实例
        /// </summary>
        /// <param name="sql">要执行的SQL语句 </param>
        /// <param name="commandType">要执行的查询类型(存储过程、SQL文本) </param>
        /// <param name="parameters">参数数组 </param>
        /// <returns>返回一SqlDataReader对象实例</returns>
        public static SqlDataReader ExecuteReader(string sql, CommandType commandType, SqlParameter[] parameters)
        {
            SqlDataReader dataReader;
            using (SqlConnection connection = new SqlConnection(_ConnStr))
            {
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    command.CommandType = commandType;
                    if (parameters != null)
                    {
                        foreach (SqlParameter parameter in parameters)
                        {
                            command.Parameters.Add(parameter);
                        }
                    }

                    try
                    {
                        dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }
            return dataReader;
        }

        #endregion 查询并返回一个SqlDataReader对象实例

        #region 查询并返回查询结果的第一行第一列

        public static Object ExecuteScalar(string sql)
        {
            return ExecuteScalar(sql, CommandType.Text, null);
        }

        public static Object ExecuteScalar(string sql, SqlParameter[] parameters)
        {
            return ExecuteScalar(sql, CommandType.Text, parameters);
        }

        /// <summary>
        /// ExecuteScalar执行一查询,返回查询结果的第一行第一列
        /// </summary>
        /// <param name="sql">要执行的SQL语句 </param>
        /// <param name="commandType">要执行的查询类型(存储过程、SQL文本) </param>
        /// <returns>返回查询结果的第一行第一列</returns>
        public static Object ExecuteScalar(string sql, CommandType commandType, SqlParameter[] parameters)
        {
            object result = null;
            using (SqlConnection connection = new SqlConnection(_ConnStr))
            {
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    command.CommandType = commandType;
                    if (parameters != null)
                    {
                        foreach (SqlParameter parameter in parameters)
                        {
                            command.Parameters.Add(parameter);
                        }
                    }

                    try
                    {
                        if (connection.State == ConnectionState.Closed)
                        {
                            connection.Open();
                        }
                        result = command.ExecuteScalar();
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }
            return result;
        }

        #endregion 查询并返回查询结果的第一行第一列

        #region 执行事务

        /// <summary>
        /// ExecuteTransaction执行一组SQL语句
        /// </summary>
        /// <param name="sqlList">要执行的SQL语句集合</param>
        /// <param name="earlyTermination">事务中有数据不满足要求是否提前终止事务</param>
        /// <returns></returns>
        public static bool ExecuteTransaction(string[] sqlList, bool earlyTermination)
        {
            return ExecuteTransaction(sqlList, null, earlyTermination);
        }

        /// <summary>
        /// ExecuteTransaction执行一组SQL语句
        /// </summary>
        /// <param name="sqlList">要执行的SQL语句集合 </param>
        /// <param name="parameters">参数数组 </param>
        /// <param name="earlyTermination">事务中有数据不满足要求是否提前终止事务</param>
        /// <returns></returns>
        public static bool ExecuteTransaction(string[] sqlList, SqlParameter[] parameters, bool earlyTermination)
        {
            using (SqlConnection connection = new SqlConnection(_ConnStr))
            {
                connection.Open();
                using (SqlTransaction transaction = connection.BeginTransaction())
                {
                    using (SqlCommand command = connection.CreateCommand())
                    {
                        command.Transaction = transaction;  //为命令指定事务

                        if (parameters != null)
                        {
                            foreach (SqlParameter parameter in parameters)
                            {
                                command.Parameters.Add(parameter);
                            }
                        }

                        try
                        {
                            bool mark = true;//标记值,记录是否有操作失败的
                            foreach (string str in sqlList)
                            {
                                command.CommandText = str;
                                if (earlyTermination)
                                {
                                    if (command.ExecuteNonQuery() <= 0)
                                    {
                                        mark = false;
                                        break;
                                    }
                                }
                                else
                                {
                                    command.ExecuteNonQuery();
                                }
                            }

                            if (!mark)//如果有某一条执行失败,就回滚
                            {
                                transaction.Rollback(); //事务回滚
                                return false;
                            }
                            else
                            {
                                transaction.Commit();   //事务提交
                                return true;
                            }
                        }
                        catch (Exception e)
                        {
                            transaction.Rollback(); //事务回滚

                            throw e;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// ExecuteTransaction执行一组SQL语句
        /// </summary>
        /// <param name="sqlAndPara">SQL语句和参数的键值对集合</param>
        /// <param name="earlyTermination">事务中有数据不满足要求是否提前终止事务</param>
        /// <returns></returns>
        public static bool ExecuteTransaction(Dictionary<string, SqlParameter[]> sqlAndPara, bool earlyTermination)
        {
            using (SqlConnection connection = new SqlConnection(_ConnStr))
            {
                connection.Open();
                using (SqlTransaction transaction = connection.BeginTransaction())
                {
                    using (SqlCommand command = connection.CreateCommand())
                    {
                        command.Transaction = transaction;  //为命令指定事务

                        try
                        {
                            if (sqlAndPara != null)
                            {
                                bool mark = true;//标记值,记录是否有操作失败的
                                foreach (KeyValuePair<string, SqlParameter[]> kvp in sqlAndPara)
                                {
                                    command.CommandText = kvp.Key;//取SQL语句
                                    command.Parameters.Clear();//清理多余的参数
                                    if (kvp.Value != null)//添加参数
                                    {
                                        foreach (SqlParameter parameter in kvp.Value)
                                        {
                                            command.Parameters.Add(parameter);
                                        }
                                    }

                                    if (earlyTermination)
                                    {
                                        if (command.ExecuteNonQuery() <= 0)
                                        {
                                            mark = false;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        command.ExecuteNonQuery();
                                    }
                                }

                                if (!mark)//如果有某一条执行失败,就回滚
                                {
                                    transaction.Rollback(); //事务回滚
                                    return false;
                                }
                                else
                                {
                                    transaction.Commit();   //事务提交
                                    return true;
                                }
                            }
                            else
                            {
                                return false;
                            }
                        }
                        catch (Exception e)
                        {
                            transaction.Rollback(); //事务回滚

                            throw e;
                        }
                    }
                }
            }
        }

        #endregion 执行事务
    }
}

调用事务

//XXX为在webconfig配置的数据库链接地址
     DBHelper.ConnString = Common.Config.DBConnString["XXX"].ToString();
            return DBHelper.ExecuteDataTable(sbSQL.ToString(), sbSQLTotal.ToString(), sqlParamList.ToArray(), ref totalCount);

注:如果有多条命令要运行在一个事务中,每条命令都必须与该事务关联起来。因为事务还与一个链接关联起来,所有这些命令也必须关联到同一链接实例上。ADO.NET事务不支持跨多个链接的事务,它总是关联到一个链接上的本地事务。

ADO.NET事务不是分布式事务,在ADO.NET事务中,很难使多个对象参与同一个事务中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值