Python

引發異常後我是否必須送出?

  • February 12, 2020

我的數據庫生成了很多孤立頁面,我試圖找出原因。

我經常在我的 python 程式碼中使用fdb 驅動程序執行此操作:

cursor = connection.cursor()
for item in list:
   try:
       cursor.execute(sql_insert_statement, (item,))
   except fdb.DatabaseError:
       log(f"Exception: duplicate found in database for {item}")
       continue

connection.commit()

由於違反主鍵唯一約束(這很好),我生成了很多異常,並且我只送出一次“主”事務,當列表中的所有項目都執行了它們的 INSERT 語句時。

這是正確的做事方式嗎?或者我是否必須在每個發生的異常之後送出(使用一個無論其結果如何finally都會觸發的子句)?try

至少,從文件cursor.execute來看,我懷疑我是否需要在每個之後送出。

當相關的工作單元完成時,您總是需要送出或回滾事務。Firebird 事務不會因錯誤而自動中止(但通常會撤消導致錯誤的語句的效果)。如果您不送出或回滾並且連接關閉,則打開的事務最終將被回滾,但這是低效的並且可能導致性能下降(取決於該事務保持打開的時間)。

因此,不,您不必在錯誤後立即送出(或回滾),您不必在工作完成時送出,或者在您的工作單元需要中止時回滾。

但是,執行時間過長的事務可能會給其他事務帶來問題,因此請確保您的工作單元(事務)盡可能短(但不要短於完成工作所需的時間)。

但是,送出或回滾失敗不會導致有關孤立頁面的錯誤。孤立頁面是 Firebird 分配數據庫頁面的結果,但未能將它們添加/註冊到對象(表、索引等),這意味著它們存在並佔用空間,但由於沒有指向它們而無法使用。

這通常是 Firebird 在寫入過程中崩潰或被殺死或分配錯誤的結果。您可能需要檢查日誌是否有錯誤。

引用自:https://dba.stackexchange.com/questions/210010