Spring 事務(wù)管理

簡單說一下事務(wù)

''是指作為單個邏輯工作單元執(zhí)行的一系列操作,要么完全地執(zhí)行,要么完全地不執(zhí)行脚草。''

四大特性(ACID)
  • 原子性(Atomicity): 指事務(wù)不可分割,要么全做披坏,要么都不做态坦。
  • 一致性(Consisitency):指事務(wù)完成前后,所有數(shù)據(jù)保持一致狀態(tài)棒拂。譬如轉(zhuǎn)賬操作伞梯,前后總額不能改后變。
  • 隔離性(Isolation):指開啟事務(wù)后帚屉,不受其它事務(wù)影響谜诫。
  • 持久性(Durability):指事務(wù)完成后,對數(shù)據(jù)庫記錄的修改是永久的攻旦。
事務(wù)隔離級別

并發(fā)的情況下會破壞掉事務(wù)的特性喻旷,導(dǎo)致操作數(shù)據(jù)的不一致。情況有以下幾種牢屋。

  • 臟讀
    當(dāng)前事務(wù)讀到另一事務(wù)未提交的數(shù)據(jù)且预。
    我向你轉(zhuǎn)賬1元,然后你看到了烙无,給我兩個饅頭锋谐,我拿到饅頭走了,接著把事務(wù)回滾了截酷。涮拗。
  • 不可重復(fù)讀
    在一個事務(wù)中,多次查詢同一記錄,結(jié)果不一致多搀。原因是別的事務(wù)修改了該條記錄并提交了歧蕉。
  • 幻讀
    開啟事務(wù)后,兩次統(tǒng)計(jì)數(shù)據(jù)庫記錄條數(shù)康铭,結(jié)果顯示不一致惯退。
    在做統(tǒng)計(jì)時就很為難。

解決辦法利用鎖機(jī)制从藤,常用的是樂觀鎖催跪,為表中添加一個vision字段;或者直接指定會話的隔離級別夷野。

注:不可重復(fù)讀和幻讀都是讀取別人以及提交的事務(wù)懊蒸,只是前者是讀取一個數(shù)據(jù)項(xiàng),后者則是針對一批悯搔。

以往對事務(wù)的操作

JDBC中

//JDBC中骑丸,事務(wù)自動提交,得手動打開妒貌,(偽代碼)
Connection conn =   
    DataSourceUtils.getConnection();  
 //開啟事務(wù)  
conn.setAutoCommit(false);  
try {  
    Object obj =   
        callback.doInConnection(conn);  
    conn.commit(); //提交事務(wù)  
    return retVal;  
}catch (Exception e) {  
    conn.rollback();//回滾事務(wù)  
    throw e;  
}finally {  
    conn.close();  
}   

后來交由SessionFactory管理

Session session = factory.openSession();
        try {
            session.beginTransaction();
            //do something
            //session.save(obj);
            session.beginTransaction().commit();
        } catch (HibernateException e) {
            session.beginTransaction().rollback();
            e.printStackTrace();
        } finally {
            if(session != null && session.isOpen()) {
                session.close();
            }
        }

再后來還是得不到滿足通危,因?yàn)槊總€方法都得這樣,重復(fù)代碼過多灌曙。而且擴(kuò)展性很差菊碟。于是想到了ThreadLocal模式,即將session放在ThreadLocal變量中在刺。并利用struts2攔截器逆害,自動開啟事務(wù),提交事務(wù)和關(guān)閉事務(wù)蚣驼。但是你需要每次都獲取當(dāng)前線程的session魄幕。

@Override
    public String intercept(ActionInvocation invocation) throws Exception {
        String ret = null;
        Session session = null;
        try {
            session = HibernateUtil.getSession();
            session.beginTransaction();
            System.out.println("********獲取session開啟事務(wù)***********");
            ret = invocation.invoke();//該攔截器負(fù)責(zé)為這次請求創(chuàng)建一個session并管理業(yè)務(wù)和關(guān)閉session
            session.getTransaction().commit();
        } catch (Exception e) {
            session.getTransaction().rollback();
            e.printStackTrace();
        } finally {
            if(session != null && session.isOpen()) {
                System.out.println("********事務(wù)結(jié)束關(guān)閉session***********");
                session.close();
            }
        }
        return ret;
    }

對的,沒錯颖杏,像下面這樣獲取session纯陨。

//ThreadLocal local
public static Session getSession() {
        Session session = local.get();
        if(session == null || !session.isOpen()) {
            session = factory.openSession();
            local.set(session);
        }
        return session;
    }

那么現(xiàn)在,Spring 來了输玷。你不再從應(yīng)用程序中主動獲取資源队丝,你只需要專注你的業(yè)務(wù)就好靡馁。像這種東西欲鹏,Spring來幫你搞定!

//既然是事務(wù)臭墨,Spring提供了一個管理事務(wù)的類赔嚎,我們將其注入IoC容器
<!-- 注入事務(wù)管理類 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
        <property name="dataSource" ref="dataSource"></property>
    </bean>
//上面是通過set方法注入了類依賴的對象,我們也要將其注入

//為類中注入了與數(shù)據(jù)庫連接用到的相關(guān)參數(shù)
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <constructor-arg name="url" value="jdbc:mysql://127.0.0.1:3306/dbname"></constructor-arg>
        <constructor-arg name="username" value="root"></constructor-arg>
        <constructor-arg name="password" value="root"></constructor-arg>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    </bean>

//這個是hibernate自身屬性配置
<!-- 配置信息建議查看源代碼 -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <!-- mappingResources 配置.hbm.xml
            源碼解釋:Set Hibernate mapping resources to be found in the class path,
                   like "example.hbm.xml" or "mypackage/example.hbm.xml".
            packagesToScan 指定注解類的包,自動掃描尤误,類似spring-component組件
            
            都是數(shù)組類型
         -->
        <property name="mappingResources">
            <list>
                <value>User.hbm.xml</value>
            </list>
        </property>
    </bean>

接下來我們要使用AOP侠畔,相關(guān)注釋很明顯了。

<!-- 定義事務(wù)通知损晤,定義了如何實(shí)施事務(wù)(實(shí)施事務(wù)的方法名和事務(wù)屬性)软棺,
        需要使用事務(wù)管理器管理事務(wù),定義了如何選擇目標(biāo)對象的方法及事務(wù)的事務(wù)屬性 
    -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager" >
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="list*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!-- 切入點(diǎn)和事務(wù)通知,切入點(diǎn)選擇實(shí)施事務(wù)的目標(biāo)對象 -->
    <aop:config>
        <aop:pointcut id="tx" expression="execution(* cn.smog.action.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="tx" />
    </aop:config>

為了方便理解,我決定畫張圖摊趾。


AopTx.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末慎王,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子被廓,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赌朋,死亡現(xiàn)場離奇詭異,居然都是意外死亡篇裁,警方通過查閱死者的電腦和手機(jī)沛慢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茴恰,“玉大人颠焦,你說我怎么就攤上這事⊥妫” “怎么了伐庭?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長分冈。 經(jīng)常有香客問我圾另,道長,這世上最難降的妖魔是什么雕沉? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任集乔,我火速辦了婚禮,結(jié)果婚禮上坡椒,老公的妹妹穿的比我還像新娘扰路。我一直安慰自己,他們只是感情好倔叼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布汗唱。 她就那樣靜靜地躺著,像睡著了一般丈攒。 火紅的嫁衣襯著肌膚如雪哩罪。 梳的紋絲不亂的頭發(fā)上授霸,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機(jī)與錄音际插,去河邊找鬼碘耳。 笑死,一個胖子當(dāng)著我的面吹牛框弛,可吹牛的內(nèi)容都是我干的辛辨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼瑟枫,長吁一口氣:“原來是場噩夢啊……” “哼愉阎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起力奋,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤榜旦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后景殷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溅呢,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年猿挚,在試婚紗的時候發(fā)現(xiàn)自己被綠了咐旧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡绩蜻,死狀恐怖铣墨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情办绝,我是刑警寧澤伊约,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站孕蝉,受9級特大地震影響屡律,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜降淮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一超埋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧佳鳖,春花似錦霍殴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至淑玫,卻和暖如春巾腕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背絮蒿。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工尊搬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人土涝。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓佛寿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親但壮。 傳聞我的和親對象是個殘疾皇子冀泻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 對大多數(shù)Java開發(fā)者來說,Spring事務(wù)管理是Spring應(yīng)用中最常用的功能蜡饵,使用也比較簡單弹渔。本文主要從三個方...
    sherlockyb閱讀 3,209評論 0 18
  • 1 什么是事務(wù) 生活中關(guān)于事務(wù)有一個常見的場景,即銀行用戶轉(zhuǎn)賬溯祸。簡單的講肢专,轉(zhuǎn)賬可以分為下面 2 個步驟: 查看用戶...
    millions_chan閱讀 611評論 0 4
  • 目前JavaWeb系統(tǒng)的框架容器基本都是使用Spring管理的,其中事務(wù)管理也是比較重要的焦辅,之前也是看過博杖,網(wǎng)上介紹...
    wiliam_wiliam閱讀 545評論 0 0
  • 事務(wù)簡介 所謂事務(wù),指的是程序中可運(yùn)行的不可分割的最小單位筷登。在生活中事務(wù)也是隨處可見的剃根。比方說你在Steam上剁手...
    樂百川閱讀 676評論 0 5
  • 看的書寫 做食物是愛的表達(dá) 我完全同意 不只是做食物 任何一個付出都是 我會打理老妹的食衣住行 就是因?yàn)閻鬯?不想...
    愛找麻煩的寶貝老妹閱讀 260評論 0 0