python实现数据库事务的回滚_在Djang中发生异常时回滚一组数据库事务

本文介绍了一个Django项目中如何使用`transaction.atomic()`管理数据库事务,确保在发生异常时能回滚更新操作。通过示例代码展示了在`set_yes()`、`set_no()`和`broken_query()`函数中如何处理`DatabaseError`,并探讨了当`broken_query()`失败时,能否回滚之前函数的数据库更改。文档表明,原子事务在异常情况下会回滚所有变更,但作者对此提出疑问并寻求确认。
摘要由CSDN通过智能技术生成

首先,this GitHub project包含了我在这篇文章中讨论和询问的代码。这是一个非专有的、简短的示例,说明了我的团队正在进行的工作。在

我在一个项目中使用Django数据库事务对表进行更新,准备转换为可用于商业目的的XML。我们通过使用transaction.atomic()上下文管理器修复了以前损坏的代码,以确保错误得到正确处理。每个UPDATE语句位于上下文管理器中,而上下文管理器又位于函数中。在程序中的另一个函数(set_yes(),set_no(),和broken_query())中有三个函数被调用:

models.pyfrom __future__ import unicode_literals

from django.db import connection, DatabaseError, transaction

import pandas as pd

from django.db import models

class TestTable(models.Model):

value1 = models.IntegerField()

value2 = models.IntegerField()

same = models.CharField(max_length=3, null=True)

def setup_table():

"""

sets up the basic table.

several rows will have matching values, some won't.

:return: None

"""

row1 = TestTable(value1=1, value2=1)

row1.save()

row2 = TestTable(value1=2, value2=1)

row2.save()

row3 = TestTable(value1=56, value2=1)

row3.save()

row4 = TestTable(value1=10, value2=10)

row4.save()

def set_yes():

"""

sets "same" column on rows with matching value1 and value2 columns to "yes"

:return: None

"""

query = '''

UPDATE db_app_testtable

SET same = 'yes'

WHERE value1 = value2

'''

try:

with transaction.atomic():

cursor = connection.cursor()

cursor.execute(query)

except DatabaseError as ex:

print "set_yes has error %s" % (ex)

raise

finally:

cursor.close()

print_table()

def set_no():

"""

sets "same" column on rows with differing value1 and value2 columns to "no"

:return: None

"""

query = '''

UPDATE db_app_testtable

SET same = 'no'

WHERE value1 != value2

'''

try:

with transaction.atomic():

cursor = connection.cursor()

cursor.execute(query)

except DatabaseError as ex:

print "set_no has error %s" % (ex)

raise

finally:

cursor.close()

print_table()

def broken_query():

"""

a function meant to break. there is no column named 'different', so this should cause

a DatabaseError to be thrown upon execution.

:return: None

"""

query = '''

UPDATE db_app_testtable

SET different = 'lol no'

WHERE value1 = value2

'''

try:

with transaction.atomic():

cursor = connection.cursor()

cursor.execute(query)

except DatabaseError as ex:

print "broken_query has error %s" % (ex)

raise

finally:

cursor.close()

...

def bulk_set():

try:

set_no()

set_yes()

broken_query()

except Exception as gen_ex:

print "Exception has occurred."

raise

如您所见,broken_query()将不起作用,这是设计的。我们正在尝试设计一个代码块,如果broken_query()失败,它将回滚set_yes()和{}所做的操作,这是不可避免的。在

鉴于django.db.transaction.atomic()的特性,这可能吗?在读取documentation时,它说,“如果代码块成功完成,更改将提交到数据库。如果出现异常,则回滚更改。“我的问题是,这是否可以扩展为使在同一代码块中调用的其他操作也回滚?在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值