Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql JPA悲观锁可能存在的性能问题_Sql_Sql Server_Jpa_Locking_Pessimistic Locking - Fatal编程技术网

Sql JPA悲观锁可能存在的性能问题

Sql JPA悲观锁可能存在的性能问题,sql,sql-server,jpa,locking,pessimistic-locking,Sql,Sql Server,Jpa,Locking,Pessimistic Locking,背景:在“我的web应用”中,用户可以购买他们选择的项目。最近,我们发现一些用户为同一个项目列表多次收费。通过同时发送两个付款请求,可以重现该问题。用户信息存储在User表中,每个用户的付款尝试都存储在payment表中,以MS SQL DB为单位。支付和用户之间的关系是多对一 问题修复:为了修复问题,我添加了一个逻辑,用于检查是否已经有一条记录标识当前用户的付款尝试已经在进行中。但是,在并发事务的情况下,当第二个事务针对付款表执行选择时,第一个事务可能不会插入记录,因此我必须暂停第二个事务,直

背景:在“我的web应用”中,用户可以购买他们选择的项目。最近,我们发现一些用户为同一个项目列表多次收费。通过同时发送两个付款请求,可以重现该问题。用户信息存储在
User
表中,每个用户的付款尝试都存储在
payment
表中,以MS SQL DB为单位。
支付
用户
之间的关系是
多对一

问题修复:为了修复问题,我添加了一个逻辑,用于检查是否已经有一条记录标识当前用户的付款尝试已经在进行中。但是,在并发事务的情况下,当第二个事务针对
付款
表执行
选择
时,第一个事务可能不会插入记录,因此我必须暂停第二个事务,直到第一个事务插入新记录。 为了做到这一点,我在并发事务之间使用了一个共享资源,这是
User
表中的一条记录。因此,并发事务流程如下所示:

  • 事务1从
    User
    表中读取数据,并在一行上设置独占锁,以防止其他事务读取、更新或删除用户记录。生成的SQL 从dbo.User userdmo0_u0中选择userdmo0_0.Id作为Id1_31_,…,其中userdmo0_0.Id=
  • 事务2将无法获取锁,因此它将等待事务1释放自己的锁
  • 事务1将INSERT…插入
    付款
    表,向DB提交更改并释放锁
  • 事务2锁定
    用户
    表记录
  • 事务处理2检查是否有正在进行的付款。由于是,因此不会在
    付款
    表中插入新记录
  • 事务2释放锁
  • 问题:修复程序运行正常。然而,我试图理解/预测的是应用程序性能的影响。如果我能得到一些很好的解释,那就太好了,因为我找不到关于性能方面的详细信息

    正如我在文档中所读到的,当使用悲观锁时,在高并发的情况下,您可能会面临应用程序缓慢的问题,因为多个事务试图同时访问同一段数据。我不认为这是我的情况,我应该担心,因为在一天中只有十几个用户在
    Payment
    表中有一条重复记录,因此根本没有高并发性

    但应用程序在高负载情况下,例如:100个用户/秒付款。MS SQL应该能够花费更多的资源来处理它创建的100个锁,对吗?此外,它是否会尝试将行锁替换为页锁或表锁