C# 后端代码中使用事务

首先来谈什么是事务

在数据库中简单的解释就是,“单个或者多个sql操作组成的一个逻辑单元”。

事务的四大特性

原子性 (Atomic)

       每一个事务都是一个不可分割的工作单位。这些操作要么全部执行,要么全都不执行。在某个操作失败后,回滚到事务执行之前的状态。
       回滚:大多数DB的事务造作只是在数据快照中进行,不修改实际数据,如果出错数据进行自然回滚。 支持简单事务的系统(例:NO-SQL)中,不会在快照上更新,而直接操作实际数据。先预演一边所有要执行的操作,如果失败则这些操作不会被执行。

一致性(Consistency)

       事务对数据完整性约束的遵循。这些约束可能包括主键约束、外键约束或是一些用户自定义约束。事务执行的前后都是合法的数据状态,不会违背任何的数据完整性。

持久性(Durability)

       事务一旦被提交,那么数据一定会被写入到数据库中并持久储存起来。

隔离性(Isolation)

       一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

可能会出现的问题
  • 问题:
  • 脏读:“后一个事务”读到了“前一个事务”未提交的更新结果,如果“前一个事务”提交失败,“后一个事务”读到的就是脏数据。
  • 不可重复读:“后一个事务” 在 “前一个事务”提交前读到的结果和提交后读到的结果可能不同而产生不可重复读。通过MVCC(Multi-Version Concurrency Control 多版本并发控制)可以在无锁的情况下,避免不可重复读。
  • 幻读:“前一个事务”新增了一条记录,”后一个事务“在“前一个事务”提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。事务串行化(多个事务的重要操作按时间排序的一个序列),才能避免幻读
  • 事务的隔离级别:
  • Read Uncommitted:最低的隔离级别,一个事务可以读到另一个事务未提交的结果,所有的并发事务问题都会发生。
  • Read Committed:只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题
  • Repeated Read:在一个事务中,对于同一份数据,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交 读取结果总是相同的。可以解决脏读、不可重复读
  • Serialization:事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。

后端代码中使用事务

使用mysql连接数据为例:

 using (MySqlConnection conn = new MySqlConnection(”数据库链接字符串“))
 {
		  if (conn.State == ConnectionState.Closed)
		  {
		      conn.Open();
		  }
		  using (MySqlTransaction trans = conn.BeginTransaction())
		  {
		   try
		   {
				   if(ExecuteSql(trans, sqlstr)==1)
				   {
				   			trans.Commit();
				   }
				   else
				   {
				  			trans.Rollback()
				   }
		    }
		    catch (Exception)
            {
                 trans.Rollback();
                 throw;
             }
		  }
}
//trans:事务 sqlstr:操作数据库的字符串
public int ExecuteSql(MysqlTransaction trans,string sqlstr)
{
			//此处可以进行封装,每次去调用
			{
							if (trans != null) cmd.Transaction = trans;
				            cmd.Connection = trans.Connection;
				            cmd.CommandText = sqlstr;
				            cmd.BindByName = true;
				            cmd.CommandType = CommandType.Text;//cmdType;
				            if (cmdParms != null)
				            {
				            	 //清除很重要 
				                cmd.Parameters.Clear();
				                foreach (MysqlParameter parm in cmdParms)
				                {
				                    if (parm.Value == null)
				                    {
				                        parm.Value = DBNull.Value;
				                    }
				                    else if (parm.Value.GetType() == typeof(string))
				                    {
				                        //parm.Size = -1;
				                        parm.Value = StringHelper.Big5ToGB(parm.Value.ToString().Trim());
				                    }
				                    else if (parm.Value.GetType() == typeof(char[]))
				                    {
				                        string charstr = new string((char[])parm.Value);
				                        parm.Value = StringHelper.Big5ToGB(charstr.Trim()).ToCharArray();
				                    }
				                }
				                cmd.Parameters.AddRange(cmdParms.ToArray());
				            }
            }
            //执行sql操作,并返回结果
            int rows = cmd.ExecuteNonQuery();
            //清除很重要
            cmd.Parameters.Clear();
            return rows;
}

这就是一个事务的基本逻辑
所需要的注意的点就是 cmd.Parameters.Clear(); 解除它对其它对象的引用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值