- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
当你这样做时:
@transaction.atomic
def update_db():
do_bulk_update()
函数运行时,是否锁定数据库?
我问的是关于 django 的原子事务: https://docs.djangoproject.com/en/1.10/topics/db/transactions/#autocommit-details
最佳答案
(我假设在这个答案中使用现代 SQL 数据库。)
事务不是锁,而是持有在操作过程中自动获取的锁。而django默认不加任何锁,所以答案是否定的,它不加锁数据库。
例如如果你这样做:
@transaction.atomic
def update_db():
cursor.execute('UPDATE app_model SET model_name TO 'bob' WHERE model_id = 1;')
# some other stuff...
您将在“其他内容”期间锁定 ID 为 1 的 app_model
行。但是直到那个查询它才被锁定。因此,如果您想确保一致性,您应该显式使用锁。
如前所述,事务不是锁,因为这会影响性能。一般来说,它们首先是轻量级机制,以确保如果您进行大量更改,而这些更改对数据库的其他用户来说一次没有意义,那么这些更改似乎会同时发生。 IE。是原子的。事务不会阻止其他用户改变数据库,实际上通常不会阻止其他用户改变您可能正在阅读的相同行。
参见 this guide和您的数据库文档(例如 postgres )以获取有关如何保护事务的更多详细信息。
当您使用 atomic
装饰器(指 the code )时,Django 本身会执行以下操作。
禁用自动提交。自动提交是一种应用程序级别的功能,它总是会立即提交事务,因此在应用程序看来似乎永远没有未完成的事务。
这告诉数据库开始一个新事务。
此时psycopg2
for postgres 将事务的隔离级别设置为READ COMMITTED
,这意味着事务中的任何读取都只会返回已提交的数据,这意味着如果另一个事务写入,在提交之前您不会看到该更改。这确实意味着如果该事务在您的事务期间提交,您可能会再次阅读并看到该值在您的事务期间发生了变化。
显然这意味着数据库没有被锁定。
运行您的代码。您所做的任何查询/变更都不会提交。
提交事务。
重新启用自动提交。
基本上在这种情况下,我们尝试使用保存点,以便在我们“回滚”“事务”时可以恢复到它们,但就数据库连接而言,我们处于同一事务中。
如前所述,数据库可能会为您的事务提供一些自动锁定,如 this doc 中所述。 .为了证明这一点,请考虑以下代码,该代码在一个表和其中的一行的 postgres 数据库上运行:
my_table
id | age
---+----
1 | 50
然后你运行这段代码:
import psycopg2 as Database
from multiprocessing import Process
from time import sleep
from contextlib import contextmanager
@contextmanager
def connection():
conn = Database.connect(
user='daphtdazz', host='localhost', port=5432, database='db_test'
)
try:
yield conn
finally:
conn.close()
def connect_and_mutate_after_seconds(seconds, age):
with connection() as conn:
curs = conn.cursor()
print('execute update age to %d...' % (age,))
curs.execute('update my_table set age = %d where id = 1;' % (age,))
print('sleep after update age to %d...' % (age,))
sleep(seconds)
print('commit update age to %d...' % (age,))
conn.commit()
def dump_table():
with connection() as conn:
curs = conn.cursor()
curs.execute('select * from my_table;')
print('table: %s' % (curs.fetchall(),))
if __name__ == '__main__':
p1 = Process(target=connect_and_mutate_after_seconds, args=(2, 99))
p1.start()
sleep(0.6)
p2 = Process(target=connect_and_mutate_after_seconds, args=(1, 100))
p2.start()
p2.join()
dump_table()
p1.join()
dump_table()
你得到:
execute update age to 99...
sleep after update age to 99...
execute update age to 100...
commit update age to 99...
sleep after update age to 100...
commit update age to 100...
table: [(1, 100)]
table: [(1, 100)]
关键是第二个进程在第一个命令完成之前启动,但在调用 update
命令之后,所以第二个进程必须等待锁定,这就是我们不这样做的原因直到 commit
年龄 99 之后,才会看到 sleep after update age to 100
。
如果你把 sleep 放在 exec 之前,你会得到:
sleep before update age to 99...
sleep before update age to 100...
execute update age to 100...
commit update age to 100...
table: [(24, 3), (100, 2)]
execute update age to 99...
commit update age to 99...
table: [(24, 3), (99, 2)]
表示在第二个进程进行更新时未获取锁,这首先发生但在第一个进程的事务期间。
关于django - Django Atomic Transaction 是否锁定数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42520917/
我对 Java 并发性比较陌生(还没有阅读 JCIP,但它在我的列表中!)并且我有一个关于锁定行为的问题。具体来说,Java 是锁定对象的引用,还是锁定对象本身? 代码示例(不是 sscce,因为我不
我的团队使用 TortoiseSVN 编写版本控制代码。有时,有人使用“获取锁定”选项。是否有可能看到解决方案中的锁? 最佳答案 http://tortoisesvn.net/docs/nightly
我在使用 SVN 时遇到了一个小问题。 当我跑 svn stat我明白了: ~ some/dir 当我跑 svn commit -m "test"我明白了:svn: working copy
我启用了 jenkins 安全性,认为它会提示我创建一个帐户。我尝试在 c:/program files/jenkins 中删除和编辑我的 config.xml 文件,但我不确定如何在没有访问权限的情
实现与 S3 结合使用的简单锁定机制的推荐方法是什么? 我想做的例子: 通过对象 ID 获取锁 从 S3 读取对象 修改数据 将对象写入 S3 释放锁 理想情况下寻找基于云的锁定机制。我可以在本地使用
找到这个here : 一般来说,在以下任何情况下,请考虑在列上创建索引: 索引列上存在引用完整性约束,或者列。索引是避免全表锁的一种方法,否则,如果您更新父表主键,则需要,合并到父表中,或从父表中删除
在我的程序中,我将把每个“ block ”数据存储在一个单独的文件中。多个线程都会读取和写入各种文件,我想避免因未正确同步而可能出现的问题。本质上,我想要一个设置,其中每个文件的行为就好像它有自己的
我想使用此script作为资源,通过使用Windows API(重置管理器)与Go for Windows中的内容相同 到目前为止,我的代码是 Rstrtmgr := syscall.NewLazyD
这里的问题是:“这些选择中的哪一个对于线程安全选择的剧院具有最佳性能?” public static List lockList = initializeLocks(); public boolean
我有一个侧面菜单,单击图标时打开,单击页面或单击菜单上的项目时关闭。我正在尝试实现锁定,因此当单击锁定图标时,即使您单击菜单项或页面,菜单也不会关闭。 我能够将图标从锁定图标更改为解锁图标,但我在停止
使用 TRueType 字体编写 SDL 程序。我调用 TTF_Init() 来初始化 TTF 并使用 TTF_OpenFont( name, size ) 打开我的字体。 我有一个例程,可以使用以下
我正在尝试调试基于运行 FreeRTOS 的 STM32F3 uC 的应用程序。我已在应用程序的线程上下文中的随机位置手动将 PSP 设置为无效值(例如 0),希望触发 memManageFault/
我有以下 C# 代码: 1. List bandEdgeList; 2. 3. bandEdgeList = CicApplication.BandEdgeCache.Where(r
我正在用骰子制作游戏。这个想法是持有/锁定骰子。我把骰子做成按钮,这样现在就可以点击它们了。示例:我抛出一个“6”和一个“1”。我点击“6”,所以现在只会抛出“1”。 我对这个有点迷失了,我需要创建
我正在使用以下代码下载约 200mb 的播客并将其写入文档目录: var podcastRequest = NSURLRequest(URL: audioUrl) NSURLConnection.se
下面的类 DoStuff 启动一个线程并同步以保护监听器对象在 null 时不被访问。 现在,当从外部访问 DoStuff 类函数 setOnProgressListener() 时,我遇到了问题,因
我正在编写一个使用巨大背景 Canvas 的网站。我试图锁定浏览器调整大小处理程序以避免滚动问题(背景越界等) 这是我第一次做一个完整的后台网站。任何有关优化的建议(png 大小 580.72 KB
我是 C# 和线程的新手,我有这个问题要解决: 我有一个处理一些数据的线程,它会不时(必要时)触发我在启动线程之前设置的事件方法 (DataProcessor)。该线程位于专有 dll 中。所以我不能
我正在使用相机,我使用的是文档中给出的完全相同的示例: http://developer.android.com/resources/samples/ApiDemos/src/com/example/
我有几个座位可供用户预订。同一时间,只有一个用户可以参与预订过程,这样同一个座位就不会被多个用户预订。在我的 Java 代码中,我使用了“synchronized”关键字来完成它。这行得通。 但是,现
我是一名优秀的程序员,十分优秀!