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

🏆作者:科技、互联网行业优质创作者
🏆专注领域:.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造
🏆欢迎关注我(Net数字智慧化基地),里面有很多高价值技术文章,是你刻苦努力也积累不到的经验,能助你快速成长。升职+涨薪!!

在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);  
            }  
        }  
    }  
}

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

悲观锁

悲观锁通常是通过在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())  
        {  
            // 在这里处理锁定的数据  
        }  
    }  
}

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

乐观锁

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

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

死锁

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

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

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

🏆欢迎关注我(Net数字智慧化基地),里面有很多高价值技术文章,是你刻苦努力也积累不到的经验,能助你升职+涨薪!!
🏆点击下方卡片关注公众号,里面有很多大佬的技术文章,能助你快速成长。还可免费领取如下15个视频教程!

回复'面试',获取C#/.NET/.NET Core面试宝典

回复'C#',领取零基础学习C#编程

回复'NET',领取.NET零基础入门到实战

回复'Linux',领取Linux从入门到精通

回复'wpf',领取高薪热门【WPF上位机+工业互联网】从零手写实战

回复'Modbus',领取初识C#+上位机Modbus通信

回复'PLC',领取C#语言与西门子PLC的通信实操

回复'blazor',领取blazor从入门到实战

回复'TypeScript',领取前端热门TypeScript系统教程

回复'vue',领取vue前端从入门到精通

回复'23P',领取C#实现23种常见设计模式

回复'MongoDB',领取MongoDB实战

回复'Trans',领取分布式事务

回复'Lock',领取分布式锁实践

回复'Docker',领取微服务+Docker综合实战

回复'K8s',领取K8s部署微服务

回复'加群',进.NET技术社区交流群 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值