同生共死的事务

我对事务的认识还很少,以前我知道数据库中有事务的存在,而不知在我们的C#程序中也可以加入事务,在程序中实现。通过我的分析,在程序中的事务好像偏向于业务方面,而在数据库中的事务,便向于数据方面。对于事务中的锁,在此我并没有进行总结,仅是总结了一下事务的概念和事务的基本用法。

数据库中的事务:

(1):事务(Transaction)是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。

(2):事务通常是以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。

COMMIT表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。

ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有以完成的操作全部撤消,滚回到事务开始的状态。

(3):事务运行的三种模式:

A:自动提交事务

          每条单独的语句都是一个事务。每个语句后都隐含一个COMMIT。

B:显式事务

       以BEGIN TRANSACTION显式开始,以COMMIT或ROLLBACK显式结束。

C:隐性事务

       在前一个事务完成时,新事务隐式启动,但每个事务仍以COMMIT或ROLLBACK显式结束。

(4):事务的特性(ACID特性)

A:原子性(Atomicity)

       事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。

B:一致性(Consistency)

       事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

C:隔离性(Isolation)

      一个事务的执行不能被其他事务干扰。

D:持续性/永久性(Durability)

      一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

 

使用事务的方式事例:

第一种:try……catch

BEGIN TRANSACTION T1

BEGIN TRY
    
      insert into [teach_info]([teach_id],[login_name],[login_pwd],[real_name],[state]) values(@id,@login_name,@pwd,@name,@state);

       delete from [tmpUser] where [login_name]=@login_name;

      COMMIT TRANSACTION T1

END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION T1;
END CATCH;

第二种:用全局变量@@error

BEGIN TRANSACTION T1
      insert into [teach_info]([teach_id],[login_name],[login_pwd],[real_name],[state]) values(@id,@login_name,@pwd,@name,@state);

     if @@Error<>0 begin

           ROLLBACK TRANSACTION T1;--回滚事务

           return;

     end
      delete from [tmpUser] where [login_name]=@login_name;

      if @@Error<>0 begin

           ROLLBACK TRANSACTION T1; --回滚事务

           return;    --别忘了返回语句,不然下面语句会继续执行,使存储过程报错

     end
      COMMIT TRANSACTION T1  --执行到这说明以上的执行都成功,提交事务

 

C#中的事务:

下面的代码中,我们想执行两个更新操作,在表T_User中将A用户的积分减100,将B用户的积分加100,如果任何其中一个操作失败,那我们就撤销。要么两个都更新数据,要么就一个也不更新。 

using ( SqlConnection conn = new SqlConnection( connectionString ) ) 

conn.Open(); 
SqlTransaction transaction = conn.BeginTransaction(); 
SqlCommand cmd1 = conn.CreateCommand(); 
cmd1.CommandType = CommandType.Text; 
cmd1.CommandText = "Updata T_User set Integral=Integral-100 where UserName=@username"; 
cmd1.Parameters.Add( new SqlParameter( "@username ", A) );
SqlCommand cmd2 = conn.CreateCommand(); 
cmd2.CommandType = CommandType.Text; 
cmd2.CommandText ="Updata T_User set Integral=Integral+100 where UserName=@username"; 
cmd2.Parameters.Add( new SqlParameter( "@username ",B) );
try 

cmd1.ExecuteNonQuery(); 
cmd2.ExecuteNonQuery(); 
//如果执行到这里,还没出错,那说明两个操作都成功了,我们就提交事务,让这两个更新都生效。 
transaction.Commit(); 

catch 

//如果执行到这里,就说明肯定有操作失败了,那么我们就回滚操作,回滚的范围就是自多调用BeginTransaction之后在该数据库连接上执行的所有事务操作。两个用户的积分保持不变 
transaction.Rollback(); 

### MySQL 事务与 MVCC 实现原理 #### 一、事务的概念及其特性 在数据库环境中,事务是指一系列作为一个整体执行的操作序列。这一系列操作要么全部成功完成并永久生效;如果其中任何一个环节失败,则整个事务都会回滚至初始状态,确保数据一致性[^1]。 - **原子性(Atomicity)**:事务中的所有操作视为单一工作单元,该单元内各项更改应同生共死。 - **一致性(Consistency)**:事务前后需保持一致的状态转换,即遵循预定义规则。 - **隔离性(Isolation)**:各并发运行的事务间相互独立不受干扰。 - **持久性(Durability)**:一旦提交,即使发生系统崩溃也能够恢复成果。 #### 二、MVCC概述 为了提升并发处理能力的同时保障读写的正常交互,MySQL引入了多版本并发控制(MVCC)[^2]。其核心在于维护同一份记录的不同时间点上的多个版本,以此支持不同类型的读取行为——快照读与当前读: - **快照读(Snapshot Read)**:无需加锁即可获取指定时刻的数据视图,适用于大多数SELECT查询场景; - **当前读(Current Read)**:涉及锁定机制以防止其他会话修改正在访问的对象实例,常用于UPDATE/DELETE以及特定条件下带有FOR UPDATE或LOCK IN SHARE MODE修饰符的SELECT语句中。 #### 三、InnoDB存储引擎下的MVCC实现细节 作为MySQL默认使用的高性能事务型表管理器,InnoDB实现了上述提到的两种主要读取模式,并通过以下组件共同作用达成高效稳定的并发控制效果[^3]: - **隐藏列**:每行记录额外携带两个隐含属性`DB_TRX_ID`(最近更新此条目的事务ID)`DB_ROLL_PTR`(指向undo日志的位置),用作判断可见性的依据之一; - **Undo Log**:当某笔交易对现有资料进行了变更时,旧版会被复制到undo log区域保存起来直到不再需要为止(比如超出了必要的保留期限或是相关联的事物已经结束); - **ReadView**:每当启动一个新的只读类事物之前都要构建一个read view对象,里面包含了创建瞬间活跃着的所有活动事物列表以及其他必要信息用来决定哪些历史版本是可以被看见的。 #### 四、可见性逻辑判定流程 针对某个给定的记录版本R,假设现在有一个正在进行中的事务T想要对其进行读取,那么根据如下准则来确定是否能观察到它: 1. 若R是在T开启之后才产生的变动,则不可见; 2. 假设R是由另一个尚未完结且位于T之前的事务S所引起的变化,此时要看S是否处于已准备提交但还未正式commit阶段: - 是 -> R暂时不可见; - 否 -> 继续下一步骤; 3. 检查产生R的那个事务U是否存在于当前T持有的readview之内: - 存在-> 不可见 ; - 缺失-> 可见; 此外还有专门针对某些特殊情况设计的小于最低限度id比较规则等辅助手段帮助更精准地界定可视范围边界条件[^4]。 ```sql -- 示例SQL展示如何查看当前系统的最小未分配事务ID SHOW ENGINE INNODB STATUS\G ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值