2012-03-15 99 views
3

我正在使用Spring 3,JPA + HibernateCMS應用程序。在那個應用程序中,我有一個服務類方法,它使用@Transactional註釋與rollBack屬性註釋。在該方法中,我使用循環將數據(即實體類)插入到表中。對於每個iteration的循環實體類都必須保存到數據庫中。但它沒有發生。提交僅在循環的執行完成並退出該方法時發生。然後它立即提交併保存。但是在這種情況下,在提交數據之前,我需要讀取數據。我嘗試使用ISOLATION LEVEL來讀取未提交的內容,但由於我使用的是默認的JPADialect,因此它不受支持。還試圖添加休眠執行jpaDialect但仍然沒有奏效。請幫助解決此問題的解決方法。還有一件事,有沒有使用傳播所需的方法。@Transactional Annotation +在循環中插入數據

+0

你似乎已經意識到你的問題是什麼。你剛剛把事務邊界放在了錯誤的地方。一旦你解決了這個問題,你應該會發現它可以按預期工作。 – 2012-03-15 14:00:27

+0

您應該能夠在不提交或更改隔離級別的情況下讀取同一事務內的未被取消的數據。據我所知這是最常見的行爲.. – 2012-03-15 16:32:32

回答

5

使用循環刪除該方法上的事務性註解。

在循環調用一個單獨的方法進行保存,使該方法事務

+0

感謝您的回覆@NimChimpsky,但是我有一個類級別的Transactional Annotation,即使我從循環方法中刪除了Transactional annoation並將它賦予同一個類中的另一個方法。它不會工作,因爲類級註釋已經存在。有沒有什麼辦法可以在類級別指定Transactional註釋來忽略該類中定義的一些方法,即不用於考慮事務管理。 – Krishna 2012-03-15 14:29:16

+0

只是刪除類級別的annoation並將其添加到您想要的每個方法 – NimChimpsky 2012-03-15 14:31:25

+1

我試過了,但是當我運行該應用程序時,它會引發TransactionRequiedException說'沒有事務正在進行中'。我創建了兩個方法,一個方法的服務類中我寫了一些業務邏輯,第二個方法是我編寫代碼來創建實體類,並引用DAO類來保存這些實體類。對於第一種方法,我沒有給出任何註釋,但是對於第二種方法,我使用傳播需要新屬性來註釋事務性註解。執行從第一個方法開始。 – Krishna 2012-03-16 08:43:38

11

你是對的,這是什麼I代表。由於事務處於孤立狀態,其他事務在提交之前無法看到它們。但玩隔離級別是一種不好的做法。我寧願建議你在一個單獨的事務中運行每一個迭代,並在裏面啓動和提交。

這是春天有點棘手,但這裏有一個例子:

public void batch() { 
    for(...) { 
     insert(...) 
    } 
} 

//necessarily in a different class! 
@Transactional 
public void insert() { 

} 

注意batch()標註有@Transactionalinsert()必須在不同的類(春季服務)。評論太長,但那就是生活。如果你不喜歡它,你可以手動使用TransactionTemplate

+0

我想使用TransactionTemplate,來解決這個問題,但我對其他服務類使用聲明性事務方法。將使用TransactionTemplate的程序化事務與聲明性事務混合起來是不好的行爲。 – Krishna 2012-03-16 10:05:00

1

您也需要去與程序性交易(Spring的TransactionTemplatePlatformTransactionManager是看班級,看到Spring Doc for programmatic transactions,或者你可以在你的循環中調用另一個事務方法,其中事務標記爲Propagation.REQUIRES_NEW,這意味着每個方法的調用都在它自己的事務中執行,見here。我認爲第二種方法需要你在不同的Spring bean上定義REQUIRES_NEW方法因爲AOP-Proxy。如果循環未在事務中執行,您也可以省略REQUIRES_NEW。