关于 c# 中SQL 事务的回滚

用事务的方式执行 无返回的sql 语句或存储过程,使用了 cmd.ExecuteNonQuery(); 后

如果没有提交事务,该方法执行并未成功,并且此时该方法涉及的表,其他事务都无法操作。

必须将该事务提交或回滚,才能继续。

 

用于DPD网路版bug的修复:ftp没有上传成功,但服务器却修改了数据库记录,可以通过事务先执行存储过程,不提交事务,如果客户端连接断开,就回滚,如果没断开,就提交。当然这会造成该事务对所涉及的表的独占。

 

代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Microsoft.Win32;
using System.Runtime.InteropServices;


namespace 制图统一平台
{
    public class M_DBSQL : M_DBInterface
    {
        private string m_dbConnectStr = string.Empty;

        private SqlTransaction sqlTrans ; //如果事务没有执行完成,那么事务中操作的表将被锁定,其他连接无法操作
        private SqlConnection sqlConn;

        #region 属性
        /// <summary>
        /// 查看数据库连接字符串
        /// </summary>
        public string StrCon
        {
            get { return m_dbConnectStr; }
            set{ m_dbConnectStr = value;}
        }

        /// <summary>
        /// 当前实例的事务
        /// </summary>
        public SqlTransaction SqlTrans
        {
            get { return sqlTrans; }
            set { sqlTrans = value; }
        }
        /// <summary>
        /// 当前实例的连接
        /// </summary>
        public SqlConnection SqlConn
        {
            get { return sqlConn; }
            set { sqlConn = value; }
        }

        #endregion

   /// <summary>
        /// 执行无返回的语句,如果失败,回滚
        /// </summary>
        /// <param name="cmdStr"></param>
        public bool excuteSql(string cmdStr)
        {
            bool re = false;
            try
            {
                sqlConn = new SqlConnection(m_dbConnectStr);

                SqlCommand cmd = sqlConn.CreateCommand();
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = cmdStr;

                if (sqlConn.State == ConnectionState.Closed)
                    sqlConn.Open();

                sqlTrans = sqlConn.BeginTransaction();
                cmd.Transaction = sqlTrans;
                try
                {
                    cmd.ExecuteNonQuery();
                  //  sqlTrans.Commit();
                    re = true;
                }
                catch (Exception e)
                {
                    try
                    {
                        sqlTrans.Rollback();//事务提交以后不能回滚
                    }
                    catch (SqlException ex)
                    {
                        if (sqlTrans.Connection != null)
                        {
                            throw new Exception("回滚失败! 异常类型: " + ex.GetType());
                        }
                    }
                }
                finally
                {
                    //sqlConn.Close();
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
            return re;
        }   

}
}

//form 中 3个按钮代码如下:

  M_DBSQL sql = new M_DBSQL();


        private void buttonexcuteSql_Click(object sender, EventArgs e)
        {

            sql.excuteSql("insert table1(num,val) values('4','f')");//delete table1

        }

        private void buttonRollBack_Click(object sender, EventArgs e)
        {
            try
            {
                if (sql.SqlTrans.Connection != null)
                {
                    sql.SqlTrans.Rollback();
                    // sql.SqlTrans.Commit();
                    sql.SqlConn.Close();
                }
             
            }
            catch(System.Exception ex)
            {
              
            }
        }

        private void buttonCommit_Click(object sender, EventArgs e)
        {
            try
            {
                if (sql.SqlTrans.Connection != null)
                {
                
                    sql.SqlTrans.Commit();
                 
                }
                if (sql.SqlConn != null)
                {
                    sql.SqlConn.Close();
                }

            }
            catch (System.Exception ex)
            {

            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用 C# 代码实现 IBatis.NET 动态批量更新数据的示例: 1. 定义 SQL 语句 在 SQL Mapper 文件定义更新语句,参考上面的示例,并加入动态 SQL。 ```xml <update id="updateBatch"> update user <dynamic prepend="set"> <isNotEmpty prepend="," property="name"> name = #name# </isNotEmpty> <isNotEmpty prepend="," property="age"> age = #age# </isNotEmpty> <isNotEmpty prepend="," property="address"> address = #address# </isNotEmpty> </dynamic> where id in <foreach open="(" close=")" separator="," collection="list" item="item"> #{item.id} </foreach> </update> ``` 其,动态 SQL 部分根据传入的参数来决定是否更新对应的字段。 2. 编写代码 ```csharp List<User> userList = new List<User>(); // 假设有三条数据需要更新 userList.Add(new User { id = 1, name = "John", age = 25, address = "New York" }); userList.Add(new User { id = 2, name = "Lucy", age = 28, address = "London" }); userList.Add(new User { id = 3, name = "Tom", age = 30 }); // 获取 SqlMapper 实例 ISqlMapper sqlMapper = Mapper.Instance(); // 开始事务 sqlMapper.BeginTransaction(); try { // 调用 SQL 语句更新数据 sqlMapper.Update("updateBatch", userList); // 提交事务 sqlMapper.CommitTransaction(); } catch(Exception ex) { // 回滚事务 sqlMapper.RollBackTransaction(); throw ex; } ``` 其,User 类为要更新的数据类型,Mapper.Instance() 获取 SqlMapper 实例,updateBatch 为定义的 SQL 语句 ID。在 try-catch 块执行 SQL 语句,如果出现异常则回滚事务,否则提交事务

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值