首页 新闻 会员 周边

EF, 实现悲观锁遇到问题,求指点。

0
[已解决问题] 解决于 2016-12-12 10:38
private static void Start()
{
            Stopwatch sw = new Stopwatch();
            sw.Start();

            Action action = () =>
            {
                using (var db = new EFDBContext())
                {
                    db.Database.ExecuteSqlCommand("select num from stock where id=1 for update;update stock set num=num-1 where id=1");
                }
            };

            List<Task> tasks = new List<Task>();
            for (var i = 0; i < 50; i++)
            {
                tasks.Add(new Task(action));
            }
            tasks.ForEach((obj) => { obj.Start(); });
            Task.WaitAll(tasks.ToArray());

            sw.Stop();
            Console.WriteLine("总耗时:" + sw.Elapsed.TotalSeconds + "");
}

 

请教个几个问题:

1. 上面的代码做悲观锁正确嘛?

2. 当50个Task一起执行时,后面抛异常,无法连接数据库(是不是超时了)?

麻烦大家指点下,谢谢。

白眉大虾的主页 白眉大虾 | 菜鸟二级 | 园豆:231
提问于:2016-12-08 21:06
< >
分享
最佳答案
0

对,抛异常可能是你连接池没有连接了,另说下你这样用ef还不如直接用ado.net

奖励园豆:5
Daniel Cai | 专家六级 |园豆:10424 | 2016-12-09 08:52

ps下,如果你本意就是你sql的话你直接update就可以了。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-09 10:11

@Daniel Cai: 感谢回复, 我改成ado.net了. 谢谢.

白眉大虾 | 园豆:231 (菜鸟二级) | 2016-12-09 11:52

@Daniel Cai: 你好, 如果不用EF,直接用ado.net处理update语句, 还需要用锁吗? 

白眉大虾 | 园豆:231 (菜鸟二级) | 2016-12-09 13:53

@待来年山花烂漫之时: 这个和用什么框架无关,如果你仅仅只需要那个更新,你在执行update的时候就会获取一个u锁。这个锁可以展开为一个s锁和一个x锁,而s锁很快就会升级为x锁(因为找到更新行要进行更新)。而u锁对其他u锁有排他,因此这里不会产生死锁。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-09 14:11

@Daniel Cai: 哦,那如果我需要先判断当前记录的数量,如果数量小于10,才更新数量, 就是先有判断,然后在确实是否需要更新值,这种场景需要先查记录加锁,在判断后更新吧?

白眉大虾 | 园豆:231 (菜鸟二级) | 2016-12-09 14:25

@待来年山花烂漫之时: 

update tb set num=num-1 where id=@id and num<10

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-09 14:29

@Daniel Cai: 哈哈, 好想法, 谢谢.

白眉大虾 | 园豆:231 (菜鸟二级) | 2016-12-09 14:30

你这样说不太妥吧?你意思是说要用悲观锁就不能用EF了吗

MayBreath | 园豆:337 (菜鸟二级) | 2020-02-02 18:26
其他回答(2)
0

为什么要多次using 而不是把  action放在using中

余昭(Ray) | 园豆:208 (菜鸟二级) | 2018-04-10 10:31
0

最烦那些什么你这样用ef还不如不用的“大佬”了

如果你们不会用EF就不要出来误导别人,菜刀只能用来切菜不能用来切肉吗?

如果你们学识不够就请不要回答。

关于EF用悲观锁不难,用事务+sql执行即可,具体可以看我博客。

MayBreath | 园豆:337 (菜鸟二级) | 2020-02-03 15:43
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册