在Django中单个connection.cursor进行多次执行安全吗?
我正在用连接的游标(connection.cursor)来执行一系列的删除操作,然后再关闭这个游标。这个过程是可以正常工作的,但我不太确定这样做是否会有什么副作用。如果有人能给点反馈,我会很感激。
from django.db import connection
c=connection.cursor()
try:
c.execute('delete from table_a')
c.execute('delete from table_b')
...
finally:
c.close()
1 个回答
5
因为你没有在事务中执行这些SQL语句,所以可能会遇到一些让人困惑的情况(比如,数据从table_a
中删除了,但table_b
中的数据却没有被删除)。
Django的文档对这种情况是这样说的:
如果你连续执行多个自定义的SQL查询,每个查询现在都在自己的事务中运行,而不是共享同一个“自动事务”。如果你需要确保操作的原子性(也就是要么全部成功,要么全部失败),你必须把这些查询放在
atomic()
中。
所以,每次调用execute()
后,结果都会立即提交,但我们希望这些操作要么全部成功,要么全部失败——就像是一组整体的更改。
可以用transaction.atomic
装饰器来包裹这个视图:
from django.db import transaction
@transaction.atomic
def my_view(request):
c = connection.cursor()
try:
c.execute('delete from table_a')
c.execute('delete from table_b')
finally:
c.close()
需要注意的是,atomic()
和整个新事务管理系统是在Django 1.6中引入的。
如果你使用的是Django版本小于1.6的,应该使用transaction.commit_on_success
装饰器。