虽然 SQLite 支持保存点时,但 sqlite3 模块中的一个设计缺陷使得它们几乎无法使用。
当启用自动提交时,保存点没有意义。当关闭时,sqlite3 会在保存点语句之前隐式提交。(事实上,它会在除了 SELECT
, INSERT
, UPDATE
, DELETE
和REPLACE
之前的任何语句之前提交)这个 Bug 有两个后果:
atomic()
块中。atomic()
。如果你正在使用 MySQL,表可能支持或不支持事务;它取决于 MySQL 版本和表的类型。(表类型是指 "InnoDB" 或 "MyISAM" 之类的东西)MySQL 事务的特性超出了本文的范围,但 MySQL 站点有 MySQL 事务的相关信息。
如果 MySQL 安装时没有支持事务,然后 Django 将始终在自动提交模式中运行:语句将在它们调用的时候被执行和提交。如果 MySQL 安装时支持了事务,Django 将像本文说的那样处理事务。
注解:只有在实现自有的事务管理时,这部分才有用。这个问题不会发生在 Django 默认模式里,并且 atomic()
会自动处理它。
在一个事务里,当对 PostgreSQL 游标的调用引发了异常(通常是 IntegrityError
),在同一事务中的随后的SQL 将会出现 "current transaction is aborted, queries ignored until end of transaction block
" 的错误 。虽然 save()
的基本用法不太可能在 PostgreSQL 中引发异常,但还有更高级的用法模式,比如保存具有唯一字段的对象,保存使用force_insert/force_update
标记,或调用自定义的 SQL。
有几种方法来从这种错误中恢复。
第一个选项是回滚整个事务。比如:
a.save() # Succeeds, but may be undone by transaction rollback
try:
b.save() # Could throw exception
except IntegrityError:
transaction.rollback()
c.save() # Succeeds, but a.save() may have been undone
调用 transaction.rollback()
回滚整个事务。任何未提交的数据库操作会被丢弃。在这个例子里, a.save()
做的改变会丢失,即使操作本身没有引发错误。
你可以使用 savepoints
来控制回滚的程度。执行可能失败的数据库操作之前,你可以设置或更新保存点;这样,如果操作失败,你可以回滚单一的错误操作,而不是回滚整个事务。比如:
a.save() # Succeeds, and never undone by savepoint rollback
sid = transaction.savepoint()
try:
b.save() # Could throw exception
transaction.savepoint_commit(sid)
except IntegrityError:
transaction.savepoint_rollback(sid)
c.save() # Succeeds, and a.save() is never undone
在这个例子里, a.save()
将不会在 b.save()
引发异常的情况下被撤销。
备案信息: 粤ICP备15087711号-2
Copyright © 2008-2024 啊嘎哇在线工具箱 All Rights.
本站所有资料来源于网络,版权归原作者所有,仅作学习交流使用,如不慎侵犯了您的权利,请联系我们。