删除和创建一起执行,遇到并发概率性删不掉,写入重复数据 返回

SqlSugar 沟通中
8 328
该叫什么 Mr、谢 发布于2周前
悬赏:0 飞吻

private static void Main(string[] args)

{

    var db = new SqlSugarScope(new SqlSugar.ConnectionConfig()

    {

        ConnectionString = "",

        DbType = DbType.PostgreSQL,

        IsAutoCloseConnection = true

    });


    //建表

    //db.CodeFirst.InitTables<Test001>();

    db.Insertable(new Test001() { id = 1, name = "init" }).ExecuteCommand();//用例代码


    var tasks = new Task[2]; // 假设我们要并发执行10个任务

    for (int i = 0; i < tasks.Length; i++)

    {

        int taskId = i;

        tasks[i] = Task.Run(() => DoWork(db, i));

    }


    Console.WriteLine("用例跑完");

    Console.ReadKey();

}


private static void DoWork(SqlSugarScope db, int id)

{

    //插入测试数据

    Console.WriteLine(id);

    db.Deleteable<Test001>().Where(x => x.id == 1).ExecuteCommand();

    db.Insertable(new Test001() { id = 1, name = $"{id}" }).ExecuteCommand();//用例代码

}


//建类

public class Test001

{

    public int id { get; set; }

    public string name { get; set; }

}


image.png


热忱回答8

  • 这种肯定不行

    0 回复
  • 这种一般要用锁

    0 回复
  • @fate sta:这种用什么锁呢?

    0 回复
  • private static void DoWork(SqlSugarScope db, int id)
    {
        var newDb=db.CopyNew();//保证并发下的线程安全
        
       newDb.BeginTran();
       //查询条件记录后锁表
       var data=newDb.Queryable<Order>().TranLock(DbLockType.Wait).Where(it=>it.Id==1).ToList();//返回条数尽量最少尽量主键
       //插入、更新等操作
       newDb.CommitTran();
    }


    0 回复
  • @fate sta还是一样不行啊


    internal class Program

    {

        private static void Main(string[] args)

        {

            var db = new SqlSugarScope(new SqlSugar.ConnectionConfig()

            {

                ConnectionString = "",

                DbType = DbType.PostgreSQL,

                IsAutoCloseConnection = true

            });


            //建表

            //db.CodeFirst.InitTables<Test001>();

            db.Insertable(new Test001() { name = "1" }).ExecuteCommand();//用例代码


            var tasks = new Task[8]; // 假设我们要并发执行10个任务

            for (int i = 0; i < tasks.Length; i++)

            {

                int taskId = i;

                tasks[i] = Task.Run(() => DoWork(db, i));

            }


            Console.WriteLine("用例跑完");

            Console.ReadKey();

        }


        private static void DoWork(SqlSugarScope db, int id)

        {

            var newDb = db.CopyNew();//保证并发下的线程安全

            newDb.BeginTran();

            newDb.Queryable<Test001>().TranLock(DbLockType.Wait).Where(it => it.name == "1").ToList();


            newDb.Deleteable<Test001>().Where(x => x.name == "1").ExecuteCommand();

            newDb.Insertable(new Test001() { name = $"{1}" }).ExecuteCommand();//用例代码

            newDb.CommitTran();

            //插入测试数据

            Console.WriteLine(id);

        }


        //建类

        public class Test001

        {

            [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]

            public int id { get; set; }


            public string name { get; set; }

        }

    }

    image.png

    0 回复
  •         using (db.AsyncLock())

            {


          newDb.Deleteable<Test001>().Where(x => x.name == "1").ExecuteCommand();

            newDb.Insertable(new Test001() { name = $"{1}" }).ExecuteCommand();//用例代码




            }

    改成这样吧,之前的方式确实不好锁因为 ,只能已存在锁

    0 回复
  • @fate sta用这个是不是不能用工作单元了  事务开在锁外面也不行

    0 回复
  • @fate sta解决了

    0 回复