簡體   English   中英

Spring @Transactional(readOnly = true)恢復屬性?

[英]Spring @Transactional(readOnly=true) revert the properties?

只是一個帶有Car-entity的簡單問題,其持久值字段值為紅色:

00  @Transactional public class MyBean{...
01    public void test(){
02        Car c = s.find(Car.class,1);
03        c.setColor("blue");
04        test1(c);
05        System.out.println(c.getColor());   
06    }
07    @Transactional(readOnly=true)
08    public void test1(Car c){
09        c.setName("black");
10    }
11  }

假設,我們處於Spring ORM TX-Transactional-Annotation環境中,具有事務語義和事務范圍的持久性上下文。

什么將打印到控制台?

  • 紅色
  • 藍色
  • 黑色

假設在調用同一實例的方法和NESTED事務傳播時啟用了事務語義:這取決於持久性上下文的范圍。

假設事務范圍內的持久性上下文: black打印到控制台。 汽車實例是分離的,因為它是在只讀事務之外獲取的,並且沒有合並到只讀事務中。 在分離的實例上調用setter是安全的(就像對setColor("blue")的調用一樣setColor("blue")

假定持久性上下文的擴展范圍: black也被打印。 來自@Transactional的javadoc

如果

當請求只讀事務時,無法解釋只讀提示的事務管理器不會引發異常。

從JPA 2.0規范的第2.4.1.2節“派生身份映射”開始:

提供者將與該關系相對應的嵌入式id屬性視為“只讀”,也就是說,在應用程序部分對它們的任何更新都不會傳播到數據庫。

但是,如果沒有引發異常,我不確定100%。 由於color屬性不是嵌入式ID,因此行為可能會有所不同。

如果可以通過代理獲得事務性語義,請參閱Adrian Shum答案

我相信您在春季陷入了AOP的陷阱。

Spring中的事務是通過AOP實現的,而Spring中的AOP是通過圍繞實際目標的代理實現的。

您已經為MyBean注釋了@Transactional。 假設其他人正在調用MyBean.test()實例,實際上它不是在直接與該對象“對話”。 有一個看起來與MyBean完全一樣的代理,但是它創建事務,然后調用實際的MyBean.test() ,然后提交/回滾。

它是這樣的:

         test()                     test()
[Caller] ------->  [MyBean Proxy]  ------> [MyBean]

然而,當你調用test1()test()這實際上意味着this.test1()這意味着你是直接調用為myBean的實例:

          [MyBean Proxy]     [MyBean] <--
                                |       |  test1(c)
                                ---------

如果不通過MyBean Proxy (負責完成事務技巧),實際上對test1()調用與Transaction無關。 這只是一個簡單的方法。

所以你知道答案。

而且,即使您設法通過代理進行調用,也不會改變故事:

          -> [MyBean Proxy]     [MyBean]
test1(c) |                         |
          -------------------------

這是因為傳遞給test1()Car實例是在圍繞test()的事務(即Hibernate會話)中檢索的,無論您在test1()更改如何,您都不會對單獨創建的Hibernate會話進行任何操作在test1() (如果您使用REQUIRED_NEW傳播)。 您只是在更改傳入對象的狀態。因此,調用test1(c)仍然只是普通方法調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM