前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SqlSugar利用“事务+乐观锁+version”解决并发下的数据一致性问题

SqlSugar利用“事务+乐观锁+version”解决并发下的数据一致性问题

作者头像
皇上得了花柳病
发布2020-05-04 21:23:20
2K0
发布2020-05-04 21:23:20
举报

1. 数据库建表

代码语言:javascript
复制
CREATE TABLE dbo.Test
(
      tId        INT IDENTITY NOT NULL
    , tName      NVARCHAR (20) NOT NULL
    , tSalary    DECIMAL (8, 2) NULL
    , tTimeStamp TIMESTAMP
    , PRIMARY KEY (tId)
)

2. 创建类

代码语言:javascript
复制
    public partial class Test
    {
        [SugarColumn(IsPrimaryKey =true,IsIdentity =true)]
        public int tId { get; set; }
        public string tName { get; set; }
        public decimal? tSalary { get; set; }
        [SugarColumn(IsOnlyIgnoreInsert = true)]
        public byte[] tTimeStamp { get; set; }
    }

3. 代码示例

代码语言:javascript
复制
static async Task Main(string[] args)
{
    for (int i = 1; i <= 5; i++)
    {
        Task.Factory.StartNew(async (id) =>
        {
            await Test((int)id);
        }, i);
    }
}

static async Task Test(int threadID)
{
    var db = SqlSugar.DB;
    for (int k = 1; k <= 50; k++)
    {
        string log = string.Empty;
        log += $"第{threadID,2}线程,第{k}次";
        //客户端从数据库获取数据
        var firstRead = await db.Queryable<Test>().SingleAsync(x => x.tId == 2);
        log += $"   name:{firstRead.tName,5} version:{BitConverter.ToString(firstRead.tTimeStamp).Replace(" - ", "")}";
        //客户端修改数据需要时间
        Thread.Sleep(10);
        try
        {
            db.Ado.BeginTran();
            log += "    事务开始";
            //提交修改前数据进行验证
            var secondRead = await db.Queryable<Test>().SingleAsync(x => x.tId == 2);
            if (BitConverter.ToString(secondRead.tTimeStamp) != BitConverter.ToString(firstRead.tTimeStamp))
            {
                log += $"    不可重复读,version:{BitConverter.ToString(secondRead.tTimeStamp).Replace(" - ", "")}";
                throw new Exception();
            }
            var data = new Test { tId = 2, tName = $"{threadID}-{k}" };
            var result = await db.Updateable(data).Where(c => c.tTimeStamp == firstRead.tTimeStamp).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            db.Ado.CommitTran();
            log += result > 0 ? $"    修改成功,当前name:{data.tName}" : "    修改失败,数据被其它线程修改";
        }
        catch (Exception)
        {
            db.Ado.RollbackTran();
            log += "    事务回滚";
        }
        finally
        {
            Console.WriteLine(log);
        };
        Thread.Sleep(10);
    }
}

分享图片

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 数据库建表
  • 2. 创建类
  • 3. 代码示例
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档