当前位置: 首页 > 面试题库 >

这个简单的代码会产生死锁。包含简单的示例程序

谢财
2023-03-14
问题内容

代码,注意值的顺序不同。因此,它在锁定行之间交替:

static void Main( string[] args )
        {
            List<int> list = new List<int>();

            for(int i = 0; i < 1000; i++ )
                list.Add( i );

            Parallel.ForEach( list, i =>
            {
                using( NamePressDataContext db = new NamePressDataContext() )
                {
                    db.ExecuteCommand( @"update EBayDescriptionsCategories set CategoryId = Ids.CategoryId from EBayDescriptionsCategories 
                        join (values (7276, 20870),(240, 20870)) as Ids(Id,CategoryId) on Ids.Id = EBayDescriptionsCategories.Id" );

                    db.ExecuteCommand( @"update EBayDescriptionsCategories set CategoryId = Ids.CategoryId from EBayDescriptionsCategories 
                        join (values (240, 20870),(7276, 20870)) as Ids(Id,CategoryId) on Ids.Id = EBayDescriptionsCategories.Id" );
                }

            } ); 
        }

表def:

CREATE TABLE [dbo].[EDescriptionsCategories](
    [CategoryId] [int] NOT NULL,
    [Id] [int] NOT NULL,
 CONSTRAINT [PK_EDescriptionsCategories] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)

例外:

Transaction (Process ID 80) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

该代码仅与WITH(TABLOCK)提示一起使用。是否可能不仅仅为了并行更新那两行就锁定整个表?


问题答案:

您的两个语句以不同的顺序获取行锁。这是死锁的典型案例。您可以通过确保所采用的锁定顺序始终处于某种全局顺序(例如,按ID顺序)来解决此问题。您可能应该将这两个UPDATE语句合并为一个,并在将客户端上的ID列表排序之前,将其发送到SQL
Server。对于许多典型的UPDATE计划,它实际上可以正常工作(尽管不能保证)。

或者,您添加重试逻辑以防检测到死锁(SqlException.Number == 1205)。这更优雅,因为它不需要更深层的代码更改。但是死锁会对性能产生影响,因此只有在低死锁率时才这样做。

如果您的并行处理生成大量更新,则可以将INSERT所有这些更新放入一个临时表中(可以同时进行),完成后,您执行一个大操作UPDATE,将所有单独的更新记录复制到主表中。您只需在示例查询中更改联接源。



 类似资料:
  • 主要内容:创建JDBC应用程序,示例代码本文章教程中将演示如何创建一个简单的JDBC应用程序的示例。 这将显示如何打开数据库连接,执行SQL查询并显示结果。 这个示例代码中涉及所有步骤,一些步骤将在本教程的后续章节中进行说明。 创建JDBC应用程序 构建JDBC应用程序涉及以下六个步骤 - 导入包:需要包含包含数据库编程所需的JDBC类的包。 大多数情况下,使用就足够了。 注册JDBC驱动程序:需要初始化驱动程序,以便可以打开与数据库的

  • 主要内容:KafkaProducer API,生产者API,配置设置,SimpleProducer应用程序,简单的消费者实例,SimpleConsumer应用程序在这一节中将创建一个使用Java客户端发布和使用消息的应用程序。 Kafka生产者客户端由以下API组成。 KafkaProducer API 下面来了解Kafka生产者API。 KafkaProducer API的核心部分是类。 类提供了一个选项,用于将Kafka代理的构造函数与以下方法连接起来。 类提供方法来异步发送消息到主题。 的

  • 本文向大家介绍java 多线程死锁详解及简单实例,包括了java 多线程死锁详解及简单实例的使用技巧和注意事项,需要的朋友参考一下 java 多线程死锁   相信有过多线程编程经验的朋友,都吃过死锁的苦。除非你不使用多线程,否则死锁的可能性会一直存在。为什么会出现死锁呢?我想原因主要有下面几个方面:     (1)个人使用锁的经验差异     (2)模块使用锁的差异     (3)版本之间的差异

  • 有人知道为什么这么简单的查询会出现两个错误吗?错误消息是: 警告:mysqli::准备():无法获取mysqli在(...)/functions.php行503 致命错误:在第504行的(…)functions.php中调用null上的成员函数bind_param()

  • 问题内容: 这个简单的代码在我用来测试的几台机器上没有产生任何声音。我正在Eclipse中运行代码,但我也尝试过使用命令行无济于事。 我可以通过获取音序器,将MIDI事件添加到音序并播放音序来成功获取声音,但是我试图做一些音序器不支持的实时音乐效果。 有任何想法吗? 使用解决方案进行编辑: 事实证明,问题在于,默认情况下,JRE并未附带音库(有趣的是,使用Sequencer起作用了,而使用Synt

  • 本文向大家介绍拳皇(Java简单的小程序)代码实例,包括了拳皇(Java简单的小程序)代码实例的使用技巧和注意事项,需要的朋友参考一下 刚开始学习Java,看完老九君的视频根据他的内容敲的代码,感觉还挺有成就感的,毕竟刚学习Java。 以上所述是小编给大家介绍的拳皇Java简单小程序详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对呐喊教程网站的