首页 > 数据库 >C#和sqlserver 如何实现 事务ACID和使用 数据库锁,悲观锁乐观锁死锁

C#和sqlserver 如何实现 事务ACID和使用 数据库锁,悲观锁乐观锁死锁

时间:2024-02-27 10:47:07浏览次数:27  
标签:事务 transaction AccountNumber C# sqlserver connection 死锁 using ACID

在C#中使用SQL Server实现事务的ACID(原子性、一致性、隔离性、持久性)属性和使用数据库锁(悲观锁和乐观锁)时,你可以通过ADO.NET的SqlConnectionSqlTransaction类来实现。下面是一些示例和概念说明。

实现ACID事务

ACID属性是事务处理的四个基本特征,它们确保事务在数据库中的正确性和可靠性。

using System;  
using System.Data;  
using System.Data.SqlClient;  
  
class Program  
{  
    static void Main()  
    {  
        string connectionString = "你的连接字符串";  
          
        using (SqlConnection connection = new SqlConnection(connectionString))  
        {  
            connection.Open();  
  
            // 开启事务  
            SqlTransaction transaction = connection.BeginTransaction();  
  
            try  
            {  
                using (SqlCommand command1 = new SqlCommand("UPDATE Account SET Balance = Balance - @Amount WHERE AccountNumber = @AccountNumber", connection, transaction))  
                {  
                    command1.Parameters.AddWithValue("@Amount", 100);  
                    command1.Parameters.AddWithValue("@AccountNumber", "12345");  
                    command1.ExecuteNonQuery();  
                }  
  
                using (SqlCommand command2 = new SqlCommand("UPDATE Account SET Balance = Balance + @Amount WHERE AccountNumber = @AccountNumber", connection, transaction))  
                {  
                    command2.Parameters.AddWithValue("@Amount", 100);  
                    command2.Parameters.AddWithValue("@AccountNumber", "67890");  
                    command2.ExecuteNonQuery();  
                }  
  
                // 提交事务  
                transaction.Commit();  
                Console.WriteLine("事务已提交");  
            }  
            catch (Exception ex)  
            {  
                // 回滚事务  
                transaction.Rollback();  
                Console.WriteLine("事务已回滚: " + ex.Message);  
            }  
        }  
    }  
}
View Code

 

 

在这个例子中,我们创建了一个事务,并在其中执行了两个更新操作。如果两个操作都成功,事务将被提交,否则事务将被回滚。

悲观锁

悲观锁通常是通过在SQL查询中使用SELECT ... FOR UPDATE语句实现的,它会在读取数据的同时锁定这些数据,以防止其他事务修改它们。

using (SqlCommand command = new SqlCommand("SELECT * FROM YourTable WHERE YourColumn = @YourValue FOR UPDATE", connection, transaction))  
{  
    command.Parameters.AddWithValue("@YourValue", "某个值");  
  
    using (SqlDataReader reader = command.ExecuteReader())  
    {  
        while (reader.Read())  
        {  
            // 在这里处理锁定的数据  
        }  
    }  
}
View Code

 

在这个例子中,FOR UPDATE语句会锁定查询结果中的行,直到事务完成。

乐观锁

乐观锁通常是通过在数据表中添加一个版本号或时间戳字段来实现的。在更新数据时,会检查版本号或时间戳是否发生了变化,如果没有变化,则更新数据并增加版本号或时间戳;如果发生了变化,则不更新数据。

在C#中,你需要自己编写逻辑来检查版本号或时间戳,并在更新数据时设置相应的条件。

死锁

死锁是指两个或更多的事务在执行过程中,因争夺资源而造成的一种互相等待的现象。当两个事务互相等待对方释放资源时,它们都无法继续执行,从而导致死锁。

SQL Server具有死锁检测机制,当检测到死锁时,它会自动选择一个事务作为“牺牲品”,并回滚该事务,从而解除死锁。在C#中,你可以通过捕获SqlException异常来检测死锁,并决定如何处理它(例如,重新尝试事务)。

总之,正确使用事务和锁是确保数据库并发操作正确性和性能的关键。在设计数据库应用程序时,需要仔细考虑何时使用事务和锁,以及如何使用它们来避免潜在的问题(如死锁)。

标签:事务,transaction,AccountNumber,C#,sqlserver,connection,死锁,using,ACID
From: https://www.cnblogs.com/forges/p/18036387

相关文章

  • three.js使用 CSS2DRenderer
    导入 import{CSS2DRenderer,CSS2DObject}from'three/examples/jsm/renderers/CSS2DRenderer';functioncreateLableObj(text,vector){letlaberDiv=document.createElement('div');//创建div容器laberDiv.className='laber_name......
  • Spring Security权限控制框架使用指南
    在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用waynboot-mall项目举例,给大家介绍常见后管系统如何引入权限控制框架SpringSecurity。大纲如下,一、什么是SpringSecurityS......
  • 开源流程引擎三巨头:activiti、flowable、camunda,最推荐使用哪个?
    From: https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247551521市场上比较有名的开源流程引擎有osworkflow、jbpm、activiti、flowable、camunda。其中:Jbpm4、Activiti、Flowable、camunda四个框架同宗同源,祖先都是Jbpm4,开发者只要用过其中一个框架,基本上就会用其它......
  • scp 命令
    scp是SSH提供的一个客户端程序,用来在两台主机之间加密传送文件(即复制文件)。简介scp是securecopy的缩写,相当于cp命令+SSH。它的底层是SSH协议,默认端口是22,相当于先使用ssh命令登录远程主机,然后再执行拷贝操作。scp主要用于以下三种复制操作。本地复制到远程。远程复......
  • ABC087D (套路题)
    难度1套路题对于多个\(x_{i}-y{i}=k_{i}\)的约束条件,考虑连边再dfs一下,如果冲突就exit#include<bits/stdc++.h>#defineendl"\n"usingnamespacestd;structnode{ longlongto,val;}p;longlongT,n,m,x,y,z,dis[100005],tot[100005];boolvis[100005];vector<nod......
  • Web自动化实战:Excel测试用例封装
    1.安装依赖pipinstallpytest-xlsx收集xlsx文件解析内容,识别测试用例将测试用例交给pytest框架参考文档:https://mp.weixin.qq.com/s/iD_KWamziFrTnDt8qpuWWA2.创建excel文件2.1基本例子注意点:文件名称:test_开头文件内容:必须有标记列插件在运行时,会解析【标记】这一......
  • A DATETIME or TIMESTAMP value can include a trailing fractional seconds part in
    MySQL::MySQL8.0ReferenceManual::13.2.2TheDATE,DATETIME,andTIMESTAMPTypeshttps://dev.mysql.com/doc/refman/8.0/en/datetime.html13.2.2 TheDATE,DATETIME,andTIMESTAMPTypesThe DATE, DATETIME,and TIMESTAMP typesarerelated.Thisse......
  • U332154 carbon 题解(期望)
    这题其实挺简单的......首先我们手模样例,对于第一组样例其实就是在1-n之间取一个数,求取到的数的期望。所以E(x)=\(\frac{1+n}{2}\)。对于第二组样例,我们首先将所有可能情况枚举出来:1010101010101010101099999999910888888889......
  • CF482B (拆位思想+实现)
    难度:2看到位运算想到拆位。因为是与所以对于\([l,r]\)区间内在二进制下,如果它是1则\([l,r]\)区间都是1,如果是0则\([l,r]\)区间内至少有1个0。因为是区间所以不难想到用线段树处理,而线段树维护的就是区间内1的个数。考虑如何处理。首先对于q拆位,1就为区间赋值,操作......
  • 服务器安装CentOS7 报错/dev/root does not exist
    报错内容通过u盘安装实体服务器时,找不到u盘报错  解决方法在报错页面出入blkid,查看u盘盘符 在安装界面按“e”修改将  vmlinuzinitrd=initrd.imginst.stage2=hd:LABEL=CentOS\xxxxquiet修改为vmlinuzinitrd=initrd.imginst.stage2=hd:/dev/sdb4quiet修改后......