2011-11-23 31 views
2

my previous question開始,我使用MySQL和InnoDB引擎,並建立了一個簡單的測試表。當我運行以下代碼:調用save()後,Django請求事務不會完全回滾。 TransactionMiddleware不像預期的那樣運行

c.execute("""insert into test(text) values('test1')""") 
conn.commit() 
c.execute("""insert into test(text) values('test2')""") 

# Raise an exception to simulate an error 
raise Exception('spam', 'eggs') 

c.execute("""insert into test(text) values('test3')""") 
conn.commit() 

我在數據庫中看到一個僅用於test1的條目,如預期的那樣。

建立相關模型類,並在Django中運行等效代碼後,(我在settings.py指定TransactionMiddleware):

def transaction_test(request): 
    t1 = Test(text='test1') 
    t2 = Test(text='test2') 
    t1.save() 

    # Raise an exception to simulate an error 
    raise Exception('spam', 'eggs')  

    t2.save() 
    return render_to_response('index.html') 

然後,我仍然看到了「測試1」的條目在表中,而我會預期整個交易已經回滾,包括'test1'的保存,根據文檔中給出的描述給出的TransactionMiddleware

有沒有其他人看到這個?是否有其他Django設置我缺少?

+0

你在哪裏開始交易? –

回答

1

你是肯定test表使用的是innodb引擎?

我可以認爲你沒有正確設置交易中間件,但如果裝飾器不能正常工作,那聽起來就像表格可能使用MyISAM

您可以在mysql外殼下面的命令檢查發動機:

show table status where name="test"; 
+0

是的 - 絕對正面的InnoDB被設置爲數據庫引擎。這就是爲什麼我包含顯示原始SQL的片段。當我使用MyISAM引擎執行此代碼時,它向數據庫提交了兩個條目;當我切換到InnoDB時,它只顯示一個條目,回滾事務。然而,試圖用Django做同樣的事情,它不管我使用哪個數據庫引擎,它都會提交保存操作。無論如何我都運行了SQL,並且它清楚地將InnoDB顯示爲「測試」表的引擎。 –

+0

好的,我第一次誤讀了您的原始SQL代碼段。我有一個最後的想法。 Django將爲名爲'myapp_test'的測試模型創建一個表,而不是'test'。你在用SQL和Django測試同一張表嗎? – Alasdair

+0

我做了其他事情:首先我在數據庫中創建表(指定innodb作爲引擎),然後運行inspectdb以生成Django模型。在這種情況下,Django仍然會創建另一個內部表,我需要追蹤(並檢查它是否使用InnoDB)? –

0

如果您正在使用django.test.TestCase而不是django.test.TransactionTestCase,那麼整個操作被包裹在回滾的交易;不同之處在於MySQL可能會在鎖定表時提交,例如混淆事物。我通過將超類切換到TransactionTestCase解決了類似的問題。

相關問題