2013-08-23 54 views
0

在HSQL中更改TRANSACTION CONTROL there can't be any active transactions。 Flyway在提交遷移X並且在從遷移X執行SQL之前輪流設置autocommitt = false並執行一些自己的語句。因此,如果遷移包含SET DATABASE TRANSACTION CONTROL語句,它將等待那些未提交的語句永遠導致應用程序掛起。 (注意:遷移前由flyway執行的語句因版本而異,例如在1.7版本中是純選擇,因此可以從LOCK更改爲MVCC,但是在我有了MVCC之後,在進一步遷移中的任何後續DDL語句都將被絞死; flyway 2.0它是選擇更新schema_version表,所以任何交易控制變更絞死;在2.2選擇更新被改爲顯式鎖定與2.0中相同的效果)長航數據庫事務控制在hsql飛路上

所以基本上是不可能改變事務控制在飛路遷移。另一方面,飛行路線discourages changes outside of its migration。任何想法,然後如何改變與flyway/hsql交易控制?

更新 另一個觀察結果是,當數據庫控制設置爲MVCC時,flyway遷移中的任何DDL語句都會掛起應用程序。所以我會在每次遷移之前設置LOCKS,然後在其之後恢復MVCC。從Flyway的角度來看,這是乾淨的解決方案嗎?

import com.googlecode.flyway.core.util.jdbc.JdbcUtils; 
public void migrate() { 
    setDbTransactionControl("LOCKS"); 
    flyway.migrate(); 
    setDbTransactionControl("MVCC"); 
} 

private void setDbTransactionControl(String mode) { 
    Connection connection = null; 
    try { 
     connection = JdbcUtils.openConnection(ds); 
     connection.createStatement().execute("SET DATABASE TRANSACTION CONTROL " + mode); 
    } catch (SQLException e) { 
     //log it 
     JdbcUtils.closeConnection(connection); 
    } finally { 
     JdbcUtils.closeConnection(connection); 
    } 
} 

回答

0

在Flyway遷移中,這是不可能的。

在Flyway開始遷移之前,它會在單獨的連接中打開一個事務以獲取其元數據表上的鎖。所以你將永遠無法執行絕對必須在沒有任何其他事務的情況下運行的語句。

您最好的選擇可能是將其設置在數據源上,以便它可以在創建時以這種方式初始化每個連接。

+0

謝謝,我用示例解決方案更新了問題 - 您認爲從Flyway架構角度來看它是正確的嗎? –

0

嘗試使用Flyway callbacksbeforeMigrateafterMigrate。兩者都與遷移事務分開。 MVCC應該用於我的應用程序,所以JDBC URL包含hsqldb.tx=mvcc。我可以在遷移遷移過程中成功更改事務模型,遷移之前使用遷移之前SET DATABASE TRANSACTION CONTROL LOCKS;遷移之後SET DATABASE TRANSACTION CONTROL MVCC;。還有Java版本的回調。我正在使用HSQLDB 2.3.3和Flyway 3.2.1。