2013-11-21 61 views
1

在我的多線程程序中,一個線程在表上刪除索引(這種情況首先發生),其他線程將記錄插入同一個表中。事實上,當嘗試刪除索引時,表被鎖定,並且插入事務變成「等待」爲什麼Drop Index需要提交?

在浪費了大量時間解決問題的非解決方案後,我發現真正的解決方案是在刪除索引後立即對提交。當發出提交時,該表被解鎖並且插入事務成功完成。

我的問題是,爲什麼?我的印象是Drop Index是一個DDL語句,因此不需要提交。 Postgres似乎證明我錯了。

+0

如果在刪除索引後需要發出COMMIT,那麼無論您使用何種工具使用連接到數據庫打開一個事務。你在使用JDBC嗎?我相信有一個切換自動提交模式。 'DROP INDEX'需要取出一個足夠長的排他鎖來執行命令,並確定沒有其他事務正在使用索引(否則你可能會得到不一致或不正確的結果)。 – bma

+0

你是對的,這是由於打開一個交易。必須承諾。 – ADTC

回答

2

我不知道Postgres,但DDL語句並不總是自動提交。在Oracle中,例如它們是,但在DB2中它們不是(您可以執行創建表 + 索引然後回滾整批)。我認爲SQL Server也需要提交(除非是自動提交)。

基本上(取決於數據庫風格),DDL語句並不總是自動提交。

+1

提交模式由您連接到數據庫的應用程序確定,DDL在大多數工具中隱式提交。 冒着迂腐的風險,它是「Postgres」或「PostgreSQL」,而不是「postgress」。 – bma

+4

[PostgreSQL中的事務性DDL:競爭分析](http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis)對不同引擎之間的事務DDL進行比較。 –

+1

我喜歡[Wikipedia關於DDL的文章](http://en.wikipedia.org/wiki/Data_definition_language#CREATE_statements)中的如何引用Postgres作爲示例。 –

3

在PostgreSQL中,所有的DDL命令都是事務性的。因此,如果您啓動事務塊,或者驅動程序爲您啓動了事務塊,或者驅動程序未處於自動提交模式,則需要提交所有DDL命令,就像其他SQL命令一樣。

其他SQL數據庫以不同的方式做到這一點。 (Nitpicking:PostgreSQL中的一些DDL命令不能在一個事務塊中運行,只能在一個事務中運行,所以你可能會認爲這些是上述「所有DDL命令」的例外,但這不完全是與你的問題相同的東西:這些命令仍然需要提交,它們不能與其他命令一起在事務中運行。)