(轉)@Transactional spring 配置事務 注意事項

近日來呆奕,發(fā)現有很多童鞋詢問:
“Mybatis整合Spring3,事務注解為何不起作用偏窝?”
“已經聲明了事務收恢,但是無法回滾。祭往。伦意。”
“Mybatis如果配置事務硼补,Spring配置沒起作用巴匀狻!”
等等已骇。离钝。。

實際上褪储,無論怎么問或者怎么貼出代碼卵渴,實際上沒有人能夠幫你解決這個問題的,首先Spring事務處理方式目前有五種鲤竹,你用的到底是哪一種呢浪读?回答問題的大神們不清楚,因此他們的回答和招在你那里不會起作用,因此碘橘,無論是哪一種事務處理方式首先你要弄明白你用的是哪一種互订,如果是雜交方式,建議選擇事務處理的第四種方式:使用tx標簽配置的攔截器蛹屿,這個簡單而且容易上手屁奏,如果用這種方式還有問題,那請往下看错负,有很大可能性是由于這些原因造成的坟瓢,我們在羅列代碼的時候一定要知其然還要知其所以然,這樣你不僅能夠快速的解決自己的問題犹撒,還能夠把該問題解決辦法與他人共享折联!

  1. 在需要事務管理的地方加@Transactional 注解。@Transactional 注解可以被應用于接口定義和接口方法识颊、類定義和類的 public 方法上 诚镰。
  2. @Transactional 注解只能應用到 public 可見度的方法上 。 如果你在 protected祥款、private 或者 package-visible 的方法上使用 @Transactional 注解清笨,它也不會報錯, 但是這個被注解的方法將不會展示已配置的事務設置刃跛。
  3. 注意僅僅 @Transactional 注解的出現不足于開啟事務行為抠艾,它僅僅 是一種元數據。必須在配置文件中使用配置元素桨昙,才真正開啟了事務行為检号。
  4. 通過 元素的 "proxy-target-class" 屬性值來控制是基于接口的還是基于類的代理被創(chuàng) 建。 如果 "proxy-target-class" 屬值被設置為 "true"蛙酪,那么基于類的代理將起作用(這時需要CGLIB庫cglib.jar在CLASSPATH中)齐苛。如果 "proxy-target-class" 屬值被設置為 "false" 或者這個屬性被省略,那么標準的JDK基于接口的代理將起作用桂塞。
<!-- JTA事務(非分布式事務)凹蜂, 事務配置的時候 ,不能指定dataSource屬性(分布式事務阁危,是有全局事務來管理數據庫鏈接的)-->   
<!-- 標準的JDK基于接口的代理將起作用 -->  
<!-- aop切面 -->  
<aop:aspectj-autoproxy proxy-target-class="false" />  
  
<!-- 基于類的代理將起作用 ,同時 cglib.jar必須在CLASSPATH中 -->  
<!-- aop切面 -->  
<aop:aspectj-autoproxy proxy-target-class="true" />  

注 解@Transactional cglib與java動態(tài)代理最大區(qū)別是代理目標對象不用實現接口, 那么注解要是寫到接口方法上炊甲,要是使用cglib代理,這是注解事物就失效了欲芹,為了保持兼容注解最好都寫到實現類方法上卿啡。

  1. Spring團隊建議在具體的類(或類的方法)上使用 @Transactional 注解,而不要使用在類所要實現的任何接口上 菱父。在接口上使用 @Transactional 注解颈娜,只能當你設置了基于接口的代理時它才生效剑逃。因為注解是 不能繼承 的,這就意味著如果正在使用基于類的代理時官辽,那么事務的設置將不能被基于類的代理所識別蛹磺,而且對象也將不會被事務代理所包裝。
  2. @Transactional 的事務開啟 同仆,或者是基于接口的 或者是基于類的代理被創(chuàng)建萤捆。所以在同一個類中一個方法調用另一個方法有事務的方法,事務是不會起作用的 俗批。
public interface PersonageTempService {  
    //刪除指定id的Personage  
    public void del(Integer Personageid) ;  
  
    //刪除指定id的Personage,flag  
    public void del(Integer Personageid,boolean flag) ;  
}  
  
public class PersonageTempServiceBean implements PersonageTempService {  
    private JdbcTemplate jdbcTemplate;  
  
    public void del(Integer Personageid){  
        try{  
                this.del(Personageid,true)  
                System.out.println("del success");  
            }catch(Exception e){  
                System.out.println("del failed");  
            }  
        }  
  
        @Transactional  
        //此時俗或,事務根本就沒有開啟, 即數據庫會默認提交該操作,即記錄別刪除掉  
        public void del(Integer Personageid,boolean flag){  
            if(flag == ture){  
                jdbcTemplate.update("del from Personage where id=?", new Object[]{Personageid}, new int[]{java.sql.Types.INTEGER});  
                throw new RuntimeException("運行期例外");  
            }  
        }  
    }  
  
    public class PersonageTempServiceBeanTest{  
        PersonageTempService ps = new PersonageTempServiceBean ();  
        ps.del(5);  
    }  
}
  1. Spring使用聲明式事務處理岁忘,默認情況下辛慰, 如果被注解的數據庫操作方法中發(fā)生了unchecked異常,所有的數據庫操作將rollback 干像;如果發(fā)生的異常是checked異常帅腌,默認情況下數 據庫操作還是會提 交的。
public interface PersonageService {  
    //刪除指定id的Personage  
    public void del(Integer Personageid) ;  
  
    //獲取Personage  
    public Personage getPersonage(Integer Personageid);  
}  
  
//PersonageServiceBean 實現了PersonageService 接口麻汰,則基于接口的還是基于類的代理 都可以實現事務  
@Transactional 
public class PersonageServiceBean implements PersonageService {  
    private JdbcTemplate jdbcTemplate;  
  
    //發(fā)生了unchecked異常,事務回滾, @Transactional  
    public void del(Integer Personageid){  
        jdbcTemplate.update("del from Personage where id=?", new Object[]{Personageid},  
        new int[]{java.sql.Types.INTEGER});  
        throw new RuntimeException("運行期例外");  
    }  
}  
public interface PersonageService {  
    //刪除指定id的Personage  
    public void delete(Integer Personageid) throws Exception;  
  
    //獲取Personage  
    public Personage getPersonage(Integer Personageid);  
}  
  
@Transactional  
public class PersonageServiceBean implements PersonageService {  
  
    //發(fā)生了checked異常,事務不回滾,即數據庫記錄仍能被刪除速客,  
    //checked的例外,需要我們在外部用try/catch語法對調用該方法的地方進行包含 
   @Transactional  
    public void delete(Integer Personageid) throws Exception{  
        jdbcTemplate.update("delete from Personage where id=?", new Object[]{Personageid},  
        new int[]{java.sql.Types.INTEGER});  
        throw new Exception("運行期例外");  
    }  
}  

但是五鲫,對于checked這種例外挽封,默認情況下它是不會進行事務回滾的,但是 如果我們需要它進行事務回滾臣镣,這時候可以在delete方法上通過@Transaction這個注解來修改它的行為。

@Transactional  
public class PersonServiceBean implements PersonService {  
  
    @Transactional(rollbackFor=Exception.class)  
    //rollbackFor這屬性指定了智亮,既使你出現了checked這種例外忆某,那么它也會對事務進行回滾  
    public void delete(Integer personid) throws Exception{  
        jdbcTemplate.update("delete from person where id=?", new Object[]{personid},  
        new int[]{java.sql.Types.INTEGER});  
        throw new Exception("運行期例外");  
    }  
}  

在PersonServiceBean這個業(yè)務bean里面,有一些事務是不需要事務管理的阔蛉,好比說獲取數據的getPersons方法弃舒,getPerson方法酿炸。因為@Transactional 放在了類的上面杖剪。

此時,可 以采用propagation這個事務屬性 @Transactional(propagation=Propagation.NOT_SUPPORTED)触机,propagation這個屬性指定了 事務傳播行為颠区,我們可以指定它不支持事務削锰,當我們這么寫了之后,Spring容器在getPersons方法執(zhí)行前就不會開啟事務 .

@Transactional  
public class PersonServiceBean implements PersonService {  
    @Transactional(propagation=Propagation.NOT_SUPPORTED)  
    //則此方法 就不會開啟事務了  
    public Person getPerson(Integer personid)  
    {  
    }  
}  
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末毕莱,一起剝皮案震驚了整個濱河市器贩,隨后出現的幾起案子颅夺,更是在濱河造成了極大的恐慌,老刑警劉巖蛹稍,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吧黄,死亡現場離奇詭異,居然都是意外死亡唆姐,警方通過查閱死者的電腦和手機拗慨,發(fā)現死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奉芦,“玉大人赵抢,你說我怎么就攤上這事≌淘模” “怎么了昌讲?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長减噪。 經常有香客問我短绸,道長,這世上最難降的妖魔是什么筹裕? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任醋闭,我火速辦了婚禮,結果婚禮上朝卒,老公的妹妹穿的比我還像新娘证逻。我一直安慰自己,他們只是感情好抗斤,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布囚企。 她就那樣靜靜地躺著,像睡著了一般瑞眼。 火紅的嫁衣襯著肌膚如雪龙宏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天伤疙,我揣著相機與錄音银酗,去河邊找鬼。 笑死徒像,一個胖子當著我的面吹牛黍特,可吹牛的內容都是我干的。 我是一名探鬼主播锯蛀,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼灭衷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旁涤?” 一聲冷哼從身側響起今布,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤经备,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后部默,有當地人在樹林里發(fā)現了一具尸體侵蒙,經...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年傅蹂,在試婚紗的時候發(fā)現自己被綠了纷闺。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡份蝴,死狀恐怖犁功,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情婚夫,我是刑警寧澤浸卦,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站案糙,受9級特大地震影響限嫌,放射性物質發(fā)生泄漏。R本人自食惡果不足惜时捌,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一怒医、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奢讨,春花似錦稚叹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至亩码,卻和暖如春季率,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蟀伸。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缅刽,地道東北人啊掏。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像衰猛,于是被迫代替她去往敵國和親迟蜜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內容

  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,867評論 6 342
  • 這部分的參考文檔涉及數據訪問和數據訪問層和業(yè)務或服務層之間的交互啡省。 Spring的綜合事務管理支持覆蓋很多細節(jié)娜睛,然...
    竹天亮閱讀 1,038評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理髓霞,服務發(fā)現,斷路器畦戒,智...
    卡卡羅2017閱讀 134,716評論 18 139
  • 對大多數Java開發(fā)者來說方库,Spring事務管理是Spring應用中最常用的功能,使用也比較簡單障斋。本文主要從三個方...
    sherlockyb閱讀 3,211評論 0 18
  • 殘雪初消薺滿園纵潦,糝羹珍美勝羔豚。吾曹舌本能知此垃环,古學工夫始可言邀层。
    XX像條狗閱讀 464評論 0 0