zoukankan      html  css  js  c++  java
  • 编程面试题:编写一个会造成数据库死锁的应用

    相信对于"开发一个会产生死锁的Java应用”这类需求,大家都能顺利完成。但是如果题目要求得更具体一些,要求这个死锁发生在数据库层面,应该怎样完成呢?

    下面我提供一种答案,采用SAP的编程语言ABAP(Advanced Business Application Programming)实现。

    我们从ABAP帮助文档中得知,SELECT SINGLE FOR UPDATE在从数据库读取一条记录时,会在数据库里将该条记录上锁。帮助文档里也提到,如果编程不恰当,会引起死锁(deadlock)。

    所以我们的答题就利用SELECT SINGLE FOR UPDATE这条语句。

    首先在数据库里插入两条记录,主键分别为Z01和Z02。

    开发两个应用,第一个应用依次锁Z01和Z02。

    REPORT zlock1.
    
    DATA: ls_prod TYPE zorder_header.
    
    SELECT SINGLE FOR UPDATE * FROM zorder_header INTO ls_prod WHERE object_id = 'Z01'.
    
    SELECT SINGLE FOR UPDATE * FROM zorder_header INTO ls_prod WHERE object_id = 'Z02'.
    
    第二个应用依次锁Z02和Z01。
    
    REPORT zlock2.
    
    DATA: ls_prod TYPE zorder_header.
    
    SELECT SINGLE FOR UPDATE * FROM zorder_header INTO ls_prod WHERE object_id = 'Z02'.
    
    SELECT SINGLE FOR UPDATE * FROM zorder_header INTO ls_prod WHERE object_id = 'Z01'.
    

    下面的步骤会造成数据库层面的死锁。

    1. 以调试模式运行第一个应用,单步执行完代码第10行,成功锁住Z01。

    2. 新开一个窗口,以调试模式运行第二个应用,单步执行完代码第10行,成功锁住Z02。

    3. 回到应用1的窗口,继续执行。此时应用1试图锁Z02,但是Z02已经被应用2锁住了,因此应用1处于等待状态。

    4. 回到应用2的窗口,继续执行。此时应用2试图锁Z01,但是Z01已经被应用1锁住了,所以应用2只有等待应用1释放出Z01的锁。但应用1此时也在等待应用2,因此造成了死锁。

    ABAP和Java不同,一旦检测到死锁,应用会抛运行时异常并自动终止,异常信息里说得很清楚:Deadlock detected while executing transaction...

  • 相关阅读:
    如何查看RabbitMQ日志,Rabbitmq Trace日志的使用
    windows激活 RabbitMQ's Management Plugin(必须)
    UNET
    边缘检测
    Huber Loss
    深度学习之自编码器AutoEncoder(一)
    PU learning简介
    机器学习-稀疏矩阵的处理
    R语言入门-安装R和Rstuido软件
    归一化 (Normalization)、标准化 (Standardization)和中心化/零均值化 (Zero-centered)
  • 原文地址:https://www.cnblogs.com/sap-jerry/p/9818889.html
Copyright © 2011-2022 走看看