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

来源:互联网 发布:淘宝客店铺做裂变 编辑:程序博客网 时间:2024/05/29 11:31

在发布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事务中,很难使多个对象参与同一个事务中。

0 0