new*_*ver 13 python mysql mysql-python
假设,我有一个修改声明:
cursor = conn.cursor()
# some code
affected_rows1 = cursor.execute(update_statement1, params1)
# some code
conn.commit()
cursor.close()
Run Code Online (Sandbox Code Playgroud)
我是否应该使用a包装代码块try ... except并在引发异常时显式回滚事务,以及应该捕获哪些MySQLdb异常?StandardError在这种情况下我常常捕获任何内容,但现在我犹豫不决,代码块甚至需要显式回滚.
以下示例稍微困难一点,我知道如果第一个更新语句成功,它确实需要显式回滚.在这种情况下,我应该抓住哪些例外:
cursor = conn.cursor()
# some code
affected_rows1 = cursor.execute(update_statement1, params1)
# some code
affected_rows2 = cursor.execute(update_statement2, params2)
#some code
conn.commit()
cursor.close()
Run Code Online (Sandbox Code Playgroud)
Red*_*ron 13
此链接显示您可以捕获的各种类型的错误.MySQLdb.Error是从中派生所有其他MySQL错误的标准基类.
我经常使用,MySQLdb.Error因为它可以让你专注于与MySQLdb本身有关的错误.相比之下,StandardError几乎可以捕获所有异常(如果您想要更好的调试功能,则不是您想要的).此外,使用MySQLdb.Error允许您显示确切的错误消息(MySQL错误号和所有),以便您可以更快地调试它.
转到问题的第一部分,在数据库语句的情况下,(通常)必须在发生错误时回滚事务(如果它们受支持).
我遵循的方法是将每个execute语句包装在try except子句(捕获MySQLdb.Error)中,如果在打印错误消息并退出之前出现错误,则使用回滚.
然而,有一个问题.在MySQLdb中,在您进行明确的调用提交之前,您对DB所做的更改实际上并未写入数据库.因此,从逻辑上讲,回滚不是必需的.
举个例子,
conn = MySQLdb.connection(db=, host=, passwd=, user=)
cur = conn.cursor()
#Say you have a table X with one entry id = 1 and total = 50
cur.execute("update X set total = 70 where id = 1")
#Actual DB has not yet changed
cur.execute("update X set total = 80 where id = 1")
#Actual DB has still not changed
Run Code Online (Sandbox Code Playgroud)
如果在没有提交的情况下退出程序,则DB中的值仍为50,因为您从未调用commit().
理想情况下,您可以这样做:
conn = MySQLdb.connection(db=, host=, passwd=, user=)
cur = conn.cursor()
#Say you have a table X with one entry id = 1 and total = 50
try:
cur.execute("update X set total = 70 where id = 1")
except MySQLdb.Error,e:
print e[0], e[1]
conn.rollback()
cur.close()
conn.close()
#print lengthy error description!!
sys.exit(2)
#Note: Value in table is still 50
#If you do conn.commit() here, value becomes 70 in table too!!
try:
cur.execute("update X set total = 80 where id = 1")
except MySQLdb.Error,e:
print e[0], e[1]
conn.rollback()
cur.close()
conn.close()
#print lengthy error description!!
sys.exit(2)
#Value in DB will be
#a) 50 if you didn't commit anywhere
#b) 70 if you committed after first execute statement
conn.commit()
#Now value in DB is 80!!
cur.close()
conn.close()
Run Code Online (Sandbox Code Playgroud)
恕我直言,如果您继续使用相同的连接,您应该回滚事务。否则,当您完成事务时,错误之前的所有内容都将被提交。对于要捕获的异常,我总是使用MySQLdb.Error,但我不确定这是否正确。
| 归档时间: |
|
| 查看次数: |
21299 次 |
| 最近记录: |