标签: database-locking

如何锁定尚不存在的InnoDB行?

我如何保证我可以搜索我的数据库中是否存在用户名,然后将该用户名作为新行插入数据库而不在SELECTINSERT语句之间进行任何拦截?

几乎就像我锁定了一个不存在的行.我想用用户名"Foo"锁定不存在的行,这样我现在可以检查它是否存在于数据库中并将其插入到数据库中(如果它尚不存在而没有任何中断).

我知道使用LOCK IN SHARE MODEFOR UPDATE存在,但据我所知,这只适用于已经存在的行.我不知道在这种情况下该怎么做.

mysql innodb locking rowlocking database-locking

17
推荐指数
3
解决办法
5262
查看次数

SQL Server如何知道锁定视图对象?

在SQL Server 2008中我有一个观点V在表AB看起来大致是

create view V as
    select * from A
    union all
    select * from B
Run Code Online (Sandbox Code Playgroud)

读取V会导致查询在基表上获取意图共享锁,但也会在视图对象本身获取意图共享锁.

很清楚为什么我们需要表上的IS锁,我们可以看到视图上的IS锁阻止了对视图底层表的并发修改.没关系.

查询计划不包含视图.它已完全编译出来,在这种情况下生成的计划是两个基表中的行的简单连接.实际上,查询计划XML中唯一提到的视图是在语句文本中.

如果U在表上添加第二个视图,则读取V不会导致任何锁定U.这排除了发动机只需要对所有意见IS锁了AB.

数据库引擎如何知道对视图进行锁定?

  • 语句文本是否再次被解析?
  • 查询规划器和底层执行之间是否还有其他信息通道来传递此信息?

有关详细信息,请参阅相应的问题dba.stackexchange.

sql sql-server view sql-server-2008 database-locking

12
推荐指数
1
解决办法
2915
查看次数

Oracle是否会在执行DML语句或仅执行行时锁定整个表

当我尝试在db表中插入/更新某些内容时,Oracle会锁定整个表还是仅锁定/更新的行?

这是可以通过外部配置控制的吗?

database oracle oracle11g database-locking

10
推荐指数
3
解决办法
5万
查看次数

8
推荐指数
1
解决办法
2万
查看次数

inno db隔离级别和锁定

我正在阅读一本关于innodb交易的手册,但仍然有很多不清楚的东西给我.例如,我不太了解以下行为:

-- client 1                             -- client 2
mysql> create table simple (col int) 
       engine=innodb; 

mysql> insert into simple values(1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into simple values(2);
Query OK, 1 row affected (0.00 sec)

mysql> select @@tx_isolation;                                                              
+-----------------+                                                                         
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |                                                                         
+-----------------+

mysql> begin;                                    
Query OK, 0 rows affected (0.01 sec)            
                                        mysql> begin;
                                        Query OK, 0 rows affected (0.00 sec)

mysql> update simple set col=10 where col=1;
Query OK, 1 row affected …
Run Code Online (Sandbox Code Playgroud)

mysql innodb transactions isolation-level database-locking

8
推荐指数
1
解决办法
4217
查看次数

Postgres 长时间运行的事务在父分区表上持有锁

TL;DR:我们有长时间运行的导入,它们似乎在父分区表上持有锁,即使没有任何东西直接引用父表。

背景

在我们的系统中,我们有inventoriesinventory_items。库存往往有 200k 左右的物品,对于我们的访问模式来说,使用本机分区对inventory_items表进行分区是有意义的inventory_id(我们使用的是 Postgres 12)。换句话说,每个库存都有自己的 inventory_items 分区表。这是通过以下 DDL 完成的:

CREATE TABLE public.inventory_items (
  inventory_id integer NOT NULL,
  /* ... */
)
PARTITION BY LIST (inventory_id);
Run Code Online (Sandbox Code Playgroud)

在我们的应用程序代码中,当通过 Web 仪表板创建库存时,我们会通过以下方式自动创建分区子 inventory_items 表:

CREATE TABLE IF NOT EXISTS inventory_items_#{inventory_id}
  PARTITION OF inventory_items
  FOR VALUES IN (#{inventory_id});
Run Code Online (Sandbox Code Playgroud)

长期进口工作阻碍创造新库存

这些库存通常每天通过 CSV 或其他方式完全重新加载/重新导入一次,并且这些导入任务有时可能需要一段时间。

我们注意到,当这些长时间导入正在运行时,不可能创建新的清单,因为如上所述,创建清单意味着创建分区子表inventory_items,并且长时间运行的导入和创建分区子表之间存在一些锁争用。网络仪表板中的库存,这很糟糕:我们不能仅仅因为发生了完全不相关的导入就阻止用户创建库存。

导入运行时尝试创建清单时的事件/锁定序列

我在 psql 中使用以下查询来确定谁持有哪些锁:

select pid, relname, mode
from pg_locks l
join pg_class t on l.relation = t.oid
where t.relkind …
Run Code Online (Sandbox Code Playgroud)

database postgresql database-partitioning database-locking postgresql-12

8
推荐指数
1
解决办法
4300
查看次数

SQL Server中的默认锁粒度是什么?

我已经彻底阅读了关于表提示的MSDN,我似乎没有找到默认的锁定粒度.假设我有以下查询:

SELECT TOP (1) * FROM MyTable WITH (UPDLOCK, READPAST) ORDER BY SomeColumn ASC;
Run Code Online (Sandbox Code Playgroud)

你看,我指定UPDLOCKREADPAST提示,但没有任何粒度提示,如TABLOCKROWLOCK.

默认情况下使用哪种粒度锁定级别?

sql-server locking granularity sql-server-2008 database-locking

6
推荐指数
1
解决办法
5098
查看次数

MongoDB中的事务锁

我正在尝试开发一个预订系统,在检查其可用性后预订不同的资产。系统首先尝试从数据库读取记录并检查正在预订的插槽是否可用。如果是这样,系统会通过将新记录插入系统来为他们预订时隙。

现在的问题是,如果有多个用户请求预订,并且由于对 db 的多个请求可以交错,那么就有可能发生这种情况。

User 1 -> read request start
User 2 -> read request start
User 1 -> read request success (booking available)
User 2 -> read request success (booking available)
User 1 -> write a new record to the db (new booking)
User 2 -> write a new record to the db (new booking) but this conflicts with User 1.
Run Code Online (Sandbox Code Playgroud)

为了避免这种情况,我理想情况下甚至在读取操作开始之前就必须获取一个集合级锁,并且只有在最终写入完成后才释放锁。

我的理解正确吗?如果可以,这可以在 MongoDB 中完成吗?

非常欢迎使用 MongoDB、Mongoose 或@tsed/mongoose 的任何解决方案。

mongoose mongodb database-locking database-concurrency

6
推荐指数
1
解决办法
5022
查看次数

Postgres 何时以及如何使用“transactionid”锁

我遇到了需要在 9.6 上解决这个问题,但是关于 9.6 或更高版本的任何信息将不胜感激。

我的应用程序在数据库调用时被阻塞,因为它试图获取transactionid另一个正在运行的事务的隐式锁,我遇到了问题。我不明白的是为什么。

我知道每个事务在开始时都会获取一个ExclusiveLock自己的事务 ID ( pg_locks )。没关系。同一页面说,“通常”,只有“更改数据库状态”的事务才会被分配一个永久 ID。我在锁表中看到了永久 ID,所以我认为这发生了。但是,描述不太清楚,因为该页面既没有说明“通常”的含义,也没有说明什么是“数据库状态的变化”。

但是后来我找不到任何信息来指定语句何时会尝试获取SharedLock某个其他交易的 a。pg_locks的唯一声明是:

当一个进程发现有必要专门等待另一个事务结束时,它会尝试获取另一个事务 ID 的共享锁(虚拟或永久 ID,具体取决于情况)

这真的很模糊。没有办法请求事务锁(至少我没有在Explicit Locking 中看到它们)

所以我正在寻找以下答案:

  1. Postgres 何时决定获取(共享)transactionid另一个事务 ID 的锁?
  2. 究竟是什么导致 Postgres 为事务分配“永久 ID”(这对我来说,弄清楚如何修复我的数据库使用不太重要,但我只是因为在任何地方都缺乏关于此的硬信息而感到困惑)
  3. transactionid在这种特殊情况下是什么让插入查询获得锁(也不太重要,因为如果我有参考,我可以自己确定)

现在,出于特殊原因,我的查询在这种情况下被阻止:

相关pg_locks内容:

x=# select locktype,transactionid,virtualtransaction,pid,mode,granted
x-# from pg_locks where transactionid = '33682979' ;
   locktype    | transactionid | virtualtransaction |  pid   |     mode      | granted 
---------------+---------------+--------------------+--------+---------------+---------
 transactionid |      33682979 | 7/27909            | 476513 | …
Run Code Online (Sandbox Code Playgroud)

postgresql database-locking postgresql-9.6

6
推荐指数
1
解决办法
2821
查看次数

如果对象已在Django中删除,如何更新或保释

我有一个Django应用程序,将对象保存到数据库中,还有一个芹菜任务,该任务定期对其中一些对象进行一些处理。问题在于,在芹菜任务已选择要处理的对象之后,但芹菜任务实际完成处理并保存之前,用户可以删除对象。因此,当celery任务确实调用时.save(),即使用户删除了该对象,该对象也会重新出现在数据库中。当然,这对于用户来说确实很诡异。

所以这是一些显示问题的代码:

def my_delete_view(request, pk):
    thing = Thing.objects.get(pk=pk)
    thing.delete()
    return HttpResponseRedirect('yay')

@app.task
def my_periodic_task():
    things = get_things_for_processing()
    # if the delete happens anywhere between here and the .save(), we're hosed
    for thing in things:
        process_thing(thing) # could take a LONG time
        thing.save()
Run Code Online (Sandbox Code Playgroud)

我考虑过尝试通过添加原子块和事务来修复它,然后在保存对象之前测试该对象是否确实存在,以进行修复:

@app.task
def my_periodic_task():
    things = Thing.objects.filter(...some criteria...)
    for thing in things:
        process_thing(thing) # could take a LONG time
        try:
            with transaction.atomic():
                # just see if it still exists:
                unused = Thing.objects.select_for_update().get(pk=thing.pk) …
Run Code Online (Sandbox Code Playgroud)

python django locking celery database-locking

5
推荐指数
1
解决办法
275
查看次数