首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

当使用Django save()更新db时,抛出异常,但为什么db仍然更新?

当使用Django的save()方法更新数据库时,如果抛出异常但数据库仍然更新的原因可能是由于Django的事务处理机制。

Django使用数据库事务来确保数据的一致性和完整性。在默认情况下,Django将每个请求视为一个事务,并在请求结束时自动提交事务。这意味着如果在保存对象时抛出异常,事务将被回滚,数据库将恢复到保存之前的状态。

然而,有时候在执行save()方法之前,可能已经进行了其他数据库操作,这些操作可能已经被提交到数据库中。在这种情况下,即使save()方法抛出异常,之前的操作仍然会生效,因为它们已经被提交到数据库中。

此外,Django的save()方法默认情况下并不会立即执行数据库操作,而是将更新操作添加到一个待执行的操作队列中。只有在事务提交或调用了特定的方法(如queryset.update())时,才会将这些操作真正执行到数据库中。因此,即使save()方法抛出异常,数据库中的更新操作也不会立即回滚,而是在事务提交时才会回滚。

为了避免这种情况,可以在save()方法调用之前使用Django的事务管理器(transaction)来手动管理事务。通过使用事务管理器的atomic()装饰器或上下文管理器,可以确保在发生异常时回滚整个事务,从而保持数据库的一致性。

总结:

当使用Django的save()方法更新数据库时,如果抛出异常但数据库仍然更新,可能是由于Django的事务处理机制。默认情况下,Django将每个请求视为一个事务,并在请求结束时自动提交事务。如果在保存对象时抛出异常,事务将被回滚,数据库将恢复到保存之前的状态。然而,如果在执行save()方法之前已经进行了其他数据库操作并已经提交到数据库中,即使save()方法抛出异常,之前的操作仍然会生效。此外,Django的save()方法并不会立即执行数据库操作,而是将更新操作添加到一个待执行的操作队列中,只有在事务提交时才会真正执行到数据库中。为了避免这种情况,可以使用Django的事务管理器手动管理事务,确保在发生异常时回滚整个事务,保持数据库的一致性。

参考链接:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

08.Django基础六之ORM中的锁和事务

这个功能使用起来非常简单,你只需要将它的配置项ATOMIC_REQUESTS设置为True。     它是这样工作的:有请求过来时,Django会在调用视图方法前开启一个事务。...尽量不要在atomic代码块中捕获异常 因为atomic块中的代码执行完的时候,Django会根据代码正常运行来执行相应的提交或者回滚操作。...通常你会在一个ORM相关的信号处理器抛出异常遇到这个行为。 捕获异常的正确方式正如上面atomic代码块所示。如果有必要,添加额外的atomic代码块来做这件事情,也就是事务嵌套。...这么做的好处是:异常发生,它能明确地告诉你那些操作需要回滚,而那些是不需要的。     为了保证原子性,atomic还禁止了一些API。...如果发生了异常Django在退出第一个父块的时候执行回滚,如果存在保存点,将回滚到这个保存点的位置,否则就是回滚到最外层的代码块。外层事务仍然能够保证原子性。

2.2K40

django-apschedule定时任务异常停止

这个是因为,关闭数据库连接,程序不一定可以正好运行在update_job,可以看到前面的get_due_jobs进行了异常捕获,如果这里抛出数据库连接异常是可以捕获到的,然后跳过后面的操作,等待下一次定时任务的执行...如果某个时机,上面连接数据库都成功了,到update_job这里异常抛出,则会导致整个线程停止,定时任务不再执行。 那如何解决该问题呢?...复现 我们将断点打在jobstore.update_job(job)上,然后使用debug模式进行调试,程序运行到断点上,将数据库关闭,然后程序继续运行,则会报错,并抛出异常,线程停止了运行。..._thread.start() time.sleep(10) 事与愿违,抛出异常异常信息如下: RuntimeError: threads can only be started...然后再次尝试复现该问题,可以发现在断开数据库后,它能够一直进行重试,线程没有停止,数据库恢复运行后,job执行成功,不再抛出异常

47660
  • django 1.8 官方文档翻译: 2-3-1 模型实例参考

    如果你需要从数据库重新加载模型的一个值,你可以使用 refresh_from_db() 方法。不带参数调用这个方法,将完成以下的动作: 模型的所有非延迟字段都更新成数据库中的当前值。...出现这种情况的原因,请参见下面的Django 如何知道是UPDATE 还是INSERT。 显式指定自增主键的值对于批量保存对象最有用,你必须有信心不会有主键冲突。 当你保存,发生了什么?...当你调用save() Django 使用下面的算法: 如果对象的主键属性为一个求值为True 的值(例如,非None 值或非空字符串),Django 将执行UPDATE。...如果对象的主键属性没有设置或者UPDATE 没有更新任何记录,Django 将执行INSERT。 现在应该明白了,保存一个新的对象,如果不能保证主键的值没有使用,你应该注意不要显式指定主键值。...保存通过延迟模型加载(only() 或defer())进行访问的模型,只有从数据库中加载的字段才会得到更新。这种情况下,有个自动的update_fields。

    1.9K10

    基于Django signals 信号作用及用法详解

    :保存的实例 raw:一个Boolean类型,如果model被全部保存则为True using:使用的数据库别名 update_fields:传递的待更新的字段集合,如果没有传递,则为None 4)post_save...using:被使用的数据库别名 7)m2m_changed() django.db.models.signals.m2m_changed 一个model的ManyToManyField发生改变的时候被发送...模型类准备好发送,即模型被创建并注册到Django的模型系统中。...3、使用信号 1)监听信号 即想要接收信号,可以使用Signals.connect()方法注册一个接收器函数,信号被发送接收器函数被调用。...”my_unique_identifier”) 如我们注册保存密码需要用到post_save,新建my_signals.py,在文件中加入下面代码: from django.db.models.signals

    2.1K20

    Django中F函数的使用示例代码详解

    F()函数 F()函数的导入 from django.db.models import F 为什么使用F()函数? 一个 F()对象代表了一个model的字段值或注释列。...开发个人博客,统计每篇文章浏览量的逻辑通常是这样写的: post = Post.objects.get(...) post.views += 1 post.save() 上面的语句已经相当简短了,实际上还有更好的办法...,就是运用F函数: from django.db.models import F post = Post.objects.get(...) post.views = F('views') + 1 post.save...或者这样: ... post.save() # 重新取值 post.refresh_from_db() Done!...到此这篇关于Django中F函数的使用的文章就介绍到这了,更多相关Django中F函数内容请搜索ZaLou.Cn以前的文章或继续浏览下面的相关文章希望大家以后多多支持ZaLou.Cn!

    1.3K20

    django 菜鸟篇+进阶篇

    要通过字典键访问该字典的值,可使用一个句点;同样,也可以通过句点来访问对象的属性;点语法也可以用来引用对象的”方法”,调用方法并没有使用圆括号而且也无法给该方法传递参数,你只能调用不需参数的方法;不允许使用负数列表索引...如果要给定第二个参数,那么该参数必须是为该模板创建Context 使用的字典。...,google结果只说到如何在django的模型层实现这个功能(下面是两个方案),但是这样在数据库层面还是没有默认当前更新时间的性质,如果用其他程序往该数据表写数据或者更新数据就会出现问题!!!...指定某些列获取值并修改了这些列,save()的时候会把相应的列更新到数据库,其他列不变(不修改、不覆盖);如果修改了only指定以外的列,save()的时候会把only制定的和这些被修改的列都更新到数据库...创建新的进程,则子进程会继承父进程的数据库连接socket,那么父子进程同时做数据库操作时会出错(数据库socket连接会抛出异常“数据库已不在”/”查询过程中出错”)

    1.9K20

    Django ForeignKey与数据库的FOREIGN KEY约束详解

    使用 on_delete=models.SET_NULL 可以使删除 Province 将关联的 City 表对应的 province_id 值设为 NULL 使用这种方式不会破坏 Django 的反向关联查询...`name` = xxx; 补充知识:关于Django模型中中定义auto_now=True 数据库中的时间并没有自动更新 django的orm关于更新数据库的方法有update和save两种方法...前提在模型中设置了auto_now=True时间戳属性,为了方便数据库自动更新时间,而 使用update更新的记录,数据库中并没有自动更新,达到我的需求。...auto_now=True自动更新,有一个条件,就是要通过django的model层。 如create或是save方法。...如果是filter之后update方法,则直接调用的是sql,不会通过model层, 所以不会自动更新此时间。所以使用save方法更新才能达到我的需求。

    2.6K10

    django使用F方法更新一个对象多个对象字段的实现

    通常情况下我们在更新数据需要先从数据库里将原数据取出后放在内存里,然后编辑某些字段或属性,最后提交更新数据库。使用F方法则可以帮助我们避免将所有数据先载入内存,而是直接生成SQL语句更新数据库。...产品很少的时候,对网站性能没影响。如果产品数量非常多,把它们信息全部先载入内存会造成很大性能浪费。...from django.db.models import F Product.objects.update(price=F(‘price’) * 1.2) 我们也可以使用F方法更新单个对象的字段,...如下所示: product = Product.objects.get(pk=5009) product.price = F('price') * 1.2 product.save() 值得注意的是当你使用...F方法对某个对象字段进行更新后,需要使用refresh_from_db()方法后才能获取最新的字段信息(非常重要!)。

    3.1K20

    MongoDB入门(二)

    固定集合是指有着固定大小的集合,达到最大值,它会自动覆盖最早的文档。 该值为 true ,必须指定 size 参数。size 数值(可选)为固定集合指定一个最大值,即字节数。...MongoDB 更新文档MongoDB 使用 update() 和 save() 方法来更新集合中的文档。updata()update() 方法用于更新已存在的文档。...multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。writeConcern :可选,抛出异常的级别。...writeConcern :可选,抛出异常的级别。...justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。writeConcern :(可选)抛出异常的级别。

    26210

    django 1.8 官方文档翻译: 2-1-3 元选项 (初稿)

    在 MySQL中使用小写字母为表命名 当你通过db_table覆写表名称,强烈推荐使用小写字母给表命名,特别是如果你用了MySQL作为后端。详见MySQL注意事项 。...select_on_save Options.select_on_save 该选项决定了Django是否采用1.6之前的 django.db.models.Model.save()算法。...旧的算法使用SELECT来判断是否存在需要更新的行。而新式的算法直接尝试使用 UPDATE。在一些小概率的情况中,一个已存在的行的UPDATE操作并不对Django可见。...关于旧式和新式两种算法,请参见django.db.models.Model.save()。...Django 1.7中修改: unique_together的约束被违反,模型校验期间会抛出ValidationError异常

    82130

    004.MongoDB数据库基础使用

    固定集合是指有着固定大小的集合,达到最大值,它会自动覆盖最早的文档。 该值为 true ,必须指定 size 参数。...multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。 writeConcern :可选,抛出异常的级别。...writeConcern :可选,抛出异常的级别。...remov并不会真正释放空间,需要执行db.repairDatabase()回收磁盘空间。 六 查询文档 6.1 简单查询 MongoDB 查询文档使用 find() 方法。...十二 异常级别 WriteConcern.NONE:没有异常抛出 WriteConcern.NORMAL:仅抛出网络错误异常,没有服务器错误异常 WriteConcern.SAFE:抛出网络错误异常、服务器错误异常

    1.4K30

    Web | Django 与数据库交互,你需要知道的 9 个技巧

    这意味着,当用户执行长时间运行的操作,工作进程会被阻塞,完成之前,其他人无法使用它。 应该没有人真正在生产中只用一个工作进程来运行 Django,但是我们仍然希望确保一个查询不会浪费太多资源太久。...比如,同一用户打开另一个选项卡并在第一次尝试「卡住」再试一次并不罕见。 这就是为什么需要使用限制(Limit)。...并非盲目的返回前 100 行,我们先确认一下,如果超过 100 行(通常是过滤以后),我们会抛出一个异常: LIMIT = 100 if Sales.objects.count() > LIMIT:... select_for_update 与 select_related 一起使用时,Django 将尝试获取查询中所有表的锁。 我们用来获取事务的代码尝试获取事务表、用户、产品、类别表的锁。...auto_now_add=True, ) 使用 auto_now_add Django 将自动使用当前时间填充该行的时间。

    2.8K40
    领券