Spring 事務(wù) 學(xué)習(xí)

筆記簡述
本學(xué)習(xí)筆記主要是介紹了事務(wù)相關(guān)的基礎(chǔ)知識绒窑,學(xué)習(xí)編程式事務(wù)和聲明式事務(wù)等不同的事務(wù)使用方法。不過現(xiàn)在實際開發(fā)中,越來越多的服務(wù)都是分布式某饰,單純的spring事務(wù)已經(jīng)無法解決數(shù)據(jù)問題了,但還是有必要去了解事務(wù)的知識點善绎。
Spring更多可查看Spring 源碼學(xué)習(xí)

目錄

Spring 事務(wù) 學(xué)習(xí)
1黔漂、事務(wù)
2、Spring 事務(wù)介紹
2.1禀酱、TransactionDefinition 屬性
2.2炬守、事務(wù)傳遞行為
2.3、事務(wù)隔離級別
3剂跟、Spring 事務(wù)使用方法
3.1减途、編程式事務(wù)
3.2、聲明式事務(wù)
3.2.1曹洽、TransactionInterceptor 方法
3.2.2鳍置、TransactionProxyFactoryBean 方法
3.2.3、命名空間 方法
3.2.4送淆、Transactional 注解 方法
4税产、總結(jié)
5、參考鏈接

1偷崩、事務(wù)

事務(wù)是值多個操作單元組成的集合辟拷,這多個操作單元組合在一起成為一個完整的工作單元,在執(zhí)行過程中要么成功阐斜,要么失敗衫冻,如果失敗了則就相當(dāng)于什么都沒有發(fā)生一樣,為了確保數(shù)據(jù)的完整性和一致性智听。就拿常見的取錢的例子吧羽杰,張三在ATM機器上取1000元錢,但是出現(xiàn)意外了到推,銀行成功扣款考赛,但是ATM機器卻因為硬件故障導(dǎo)致出鈔失敗,張三就損失了1000元錢莉测;如果銀行扣款失敗颜骤,但是卻順利取出了錢,銀行就損失了1000元錢捣卤。在現(xiàn)實中這種情況需要絕對被解決忍抽,這就可以使用事務(wù)去解決了八孝,銀行扣款和ATM出鈔分為2個操作單元,只有2個都成功了鸠项,才意味著成功取錢干跛,否則就認為操作失敗,所有的數(shù)據(jù)都回滾到發(fā)生之前祟绊。

事務(wù)一般和數(shù)據(jù)連接綁定在一起使用楼入,在操作數(shù)據(jù)庫時,一般都是1牧抽、3嘉熊、4步,但是加上事務(wù)必須得捕獲異常扬舒,然后進行回滾操作阐肤,也就多了2、5兩步了讲坎。其中回滾主要是使用類似binlog等方式恢復(fù)數(shù)據(jù)

try{
    1. con = getConnection();  // 獲取連接
    2. con.setAutoCommit(false);  // 設(shè)置是否進行自動提交
    3. doing....             // 拼接sql
    4. con.commit();      // 提交操作
} catch(RuntimeException ex){  // 不一定就是運用時的異常才會被捕獲孕惜,看用戶自定義設(shè)置
    5. con.rollback();   //回滾事務(wù)
} 

多說一句,在接下來的學(xué)習(xí)中會了解到如今的實際場景中晨炕,其實事務(wù)使用的并不是很多诊赊。事務(wù)其實就類似于對一個數(shù)據(jù)庫連接進行鎖操作一樣(這是自己描述的,并沒有這個具體的說法府瞄,只是為了便于理解),而現(xiàn)在很多服務(wù)都是分布式架構(gòu)的碘箍,必然存在多個數(shù)據(jù)庫連接遵馆,而各個數(shù)據(jù)庫連接之間沒有關(guān)系,鎖住或者控制一個數(shù)據(jù)庫連接無法解決問題丰榴,況且還有更重要的冪等性問題

事務(wù)包含了4個特性货邓,分別是原子性(Atomicity),一致性(Consistency)四濒,隔離性(Isolation)换况,持久性(Durability)

  • 原子性(Atomicity):事務(wù)是一個原子操作,由一系列動作組成盗蟆。事務(wù)的原子性確保動作要么全部完成戈二,要么完全不起作用。
  • 一致性(Consistency):一旦事務(wù)完成(不管成功還是失斣省)觉吭,系統(tǒng)必須確保它所建模的業(yè)務(wù)處于一致的狀態(tài),而不會是部分完成部分失敗仆邓。在現(xiàn)實中的數(shù)據(jù)不應(yīng)該被破壞鲜滩。
  • 隔離性(Isolation):可能有許多事務(wù)會同時處理相同的數(shù)據(jù)伴鳖,因此每個事務(wù)都應(yīng)該與其他事務(wù)隔離開來,防止數(shù)據(jù)損壞徙硅。
  • 持久性(Durability):一旦事務(wù)完成榜聂,無論發(fā)生什么系統(tǒng)錯誤,它的結(jié)果都不應(yīng)該受到影響嗓蘑,這樣就能從任何系統(tǒng)崩潰中恢復(fù)過來须肆。通常情況下,事務(wù)的結(jié)果被寫到持久化存儲器中脐往。

2休吠、Spring 事務(wù)介紹

主要介紹下spring中的事務(wù)的基本情況。在spring中必須得由Spring中的某些對象接管原本的數(shù)據(jù)庫連接业簿,然后通過各種方式添加如上偽代碼顯示的2瘤礁、5兩步完成添加事務(wù)的操作。

spring中提供事務(wù)的接口是PlatformTransactionManager接口類梅尤,具體實現(xiàn)有jdbc管理類等柜思,具體如下圖


image
// 獲得需要的TransactionStatus對象,是一個事物的屬性對象
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
// 提交
void commit(TransactionStatus status) throws TransactionException;
// 回滾
void rollback(TransactionStatus status) throws TransactionException;

2.1、TransactionDefinition 屬性

事務(wù)管理中必然需要管理各個事務(wù)的屬性信息巷燥,而這些都存儲在TransactionDefinition 接口類中

public interface TransactionDefinition { 
    int getPropagationBehavior();
    //返回事務(wù)的傳播行為赡盘。 
    int getIsolationLevel();
    //返回事務(wù)的隔離級別,事務(wù)管理器根據(jù)它來控制另外一個事務(wù)可以看到本事務(wù)內(nèi)的哪些數(shù)據(jù)缰揪。 
    int getTimeout();
    //返回事務(wù)必須在多少秒內(nèi)完成陨享,某些事務(wù)操作可能比較耗時,默認為-1
    boolean isReadOnly();
    //事務(wù)是否只讀钝腺,事務(wù)管理器能夠根據(jù)這個返回值進行優(yōu)化抛姑,確保事務(wù)是只讀的。 
}

2.2艳狐、事務(wù)傳遞行為

事務(wù)傳遞是指定硝,在開始進行事務(wù)處理的時候,已經(jīng)存在了一個上下文毫目,此時該如何執(zhí)行的這么一個過程蔬啡。

  • TransactionDefinition.PROPAGATION_REQUIRED:如果當(dāng)前存在事務(wù),則加入該事務(wù)镀虐;如果當(dāng)前沒有事務(wù)箱蟆,則創(chuàng)建一個新的事務(wù)。
  • TransactionDefinition.PROPAGATION_REQUIRES_NEW:創(chuàng)建一個新的事務(wù)粉私,如果當(dāng)前存在事務(wù)顽腾,則把當(dāng)前事務(wù)掛起。
  • TransactionDefinition.PROPAGATION_SUPPORTS:如果當(dāng)前存在事務(wù),則加入該事務(wù)抄肖;如果當(dāng)前沒有事務(wù)久信,則以非事務(wù)的方式繼續(xù)運行。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式運行漓摩,如果當(dāng)前存在事務(wù)裙士,則把當(dāng)前事務(wù)掛起。
  • TransactionDefinition.PROPAGATION_NEVER:以非事務(wù)方式運行管毙,如果當(dāng)前存在事務(wù)腿椎,則拋出異常。
  • TransactionDefinition.PROPAGATION_MANDATORY:如果當(dāng)前存在事務(wù)夭咬,則加入該事務(wù)啃炸;如果當(dāng)前沒有事務(wù),則拋出異常卓舵。
  • TransactionDefinition.PROPAGATION_NESTED:如果當(dāng)前存在事務(wù)南用,則創(chuàng)建一個事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運行; 如果當(dāng)前沒有事務(wù)掏湾,則該取值等價于TransactionDefinition.PROPAGATION_REQUIRED裹虫。

2.3、事務(wù)隔離級別

事務(wù)隔離是指多個事務(wù)之間的隔離程度融击,當(dāng)兩個事務(wù)對數(shù)據(jù)庫的同一條數(shù)據(jù)進行讀寫操作時筑公,就會因為不同等級的隔離,出現(xiàn)不同的情況尊浪,當(dāng)然隔離的程度越大性能消耗的也更多匣屡。

  • TransactionDefinition.ISOLATION_DEFAULT:這是默認值,表示使用底層數(shù)據(jù)庫的默認隔離級別拇涤。對大部分數(shù)據(jù)庫而言耸采,通常這值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED:該隔離級別表示一個事務(wù)可以讀取另一個事務(wù)修改但還沒有提交的數(shù)據(jù)工育。該級別不能防止臟讀和不可重復(fù)讀,因此很少使用該隔離級別搓彻。
  • TransactionDefinition.ISOLATION_READ_COMMITTED:該隔離級別表示一個事務(wù)只能讀取另一個事務(wù)已經(jīng)提交的數(shù)據(jù)如绸。該級別可以防止臟讀,這也是大多數(shù)情況下的推薦值旭贬。
  • TransactionDefinition.ISOLATION_REPEATABLE_READ:該隔離級別表示一個事務(wù)在整個過程中可以多次重復(fù)執(zhí) 行某個查詢怔接,并且每次返回的記錄都相同。即使在多次查詢之間有新增的數(shù)據(jù)滿足該查詢稀轨,這些新增的記錄也會被忽略扼脐。該級別可以防止臟讀和不可重復(fù)讀。
  • TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事務(wù)依次逐個執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾瓦侮,也就是說艰赞,該級別可以防止臟讀、不可重復(fù)讀以及幻讀肚吏。但是這將嚴重影響程序的性能方妖。通常情況下也不會用到該級別。

3罚攀、Spring 事務(wù)使用方法

編寫一些demo党觅,實踐中如何具體使用事務(wù)達到我們想要的目的(如下例子有參考網(wǎng)上實例,覺得這個例子挺好)

數(shù)據(jù)庫表結(jié)構(gòu)


image
public class Money {

    private Long id;
    private String name;
    private Long moneyNum;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getMoneyNum() {
        return moneyNum;
    }

    public void setMoneyNum(Long moneyNum) {
        this.moneyNum = moneyNum;
    }

    @Override
    public String toString() {
        return "Money{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", moneyNum=" + moneyNum +
                '}';
    }
}
@Component("moneyDao")
public class MoneyDao {

    @Resource
    private JdbcTemplate jdbcTemplate;

    public void add(Long id, String name, Long moneyNum){

        String sql = "insert into test_money(id, name, money) value(?, ?, ?)";

        int record = jdbcTemplate.update(sql, id, name, moneyNum);
        System.out.println(record);
    }

    public void update(Long id, Long moneyNum){
        String sql = "update test_money set money = ? where id = ?";

        int record = jdbcTemplate.update(sql, moneyNum, id);
        System.out.println(record);
    }
}
<context:component-scan base-package="com.demo.jdbc" />

<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/test"/>
    <property name="username" value="root"/>
    <property name="password" value="......"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg name="dataSource" ref="dataSource" />
</bean>

3.1斋泄、編程式事務(wù)

編程式代碼也就是硬編碼的形式杯瞻,TransactionTemplate模板類用于簡化事務(wù)管理,事務(wù)管理由模板類定義炫掐,而具體操作需要通過TransactionCallback回調(diào)接口或TransactionCallbackWithoutResult回調(diào)接口指定魁莉,通過調(diào)用模板類的參數(shù)類型為TransactionCallback或TransactionCallbackWithoutResult的execute方法來自動享受事務(wù)管理。

  • TransactionCallback 實現(xiàn)doInTransactionWithoutResult方法卒废,里面填充事務(wù)需要管理的代碼沛厨,有返回值
  • TransactionCallbackWithoutResult 繼承自TransactionCallback接口,無需返回數(shù)據(jù)

如果有看這兩個代碼摔认,會發(fā)現(xiàn)其實調(diào)用的是同一個地方逆皮,只是無數(shù)據(jù)返回的是null罷了

我們當(dāng)前就選擇無數(shù)據(jù)返回作為例子

<!-- 配置SpringJdbc的事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--配置事務(wù)管理模板,Spring為了簡化事務(wù)管理的代碼而提供的類-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="transactionManager"/>
    <!--  這里還可以設(shè)置事務(wù)隔離的級別屬性-->
</bean>
public void change(){
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
            moneyDao.update(1L, 30L);
            // 添加70,移到李四上参袱,當(dāng)然這只是例子沒有做查詢減少的操作电谣,直接更新罷了
            test();
            moneyDao.update(2L, 120L);
        }
    });
}

/**
 * 假設(shè)拋出了錯誤
 */
private void test(){
    throw new IndexOutOfBoundsException("demo test");
}

如上代碼所示,其中就有使用到上面說的TransactionTemplate模板類抹蚀,在這里沒有貼出具體的調(diào)用方法剿牺,自行注入執(zhí)行,兩個更新sql代碼操作包裹在doInTransactionWithoutResult方法中环壤。

其中包含了拋出個運行時錯誤晒来,如果沒有事務(wù),那第一個操作會成功郑现,第二個會失敗湃崩,但是這就導(dǎo)致了數(shù)據(jù)錯誤的情況,添加了事務(wù)接箫,則同時成功或者回滾到操作前攒读。

在運行前還需要提一點的是,上一段話說了是拋出運行時錯誤辛友,可是如果是sql本身或者事務(wù)具體執(zhí)行的導(dǎo)致的異常呢薄扁?這個就需要取到TransactionStatus這個對象的數(shù)據(jù),進行rollback操作,具體的原因后續(xù)的源碼分析中會解答的邓梅。

如下圖脱盲,在有運行中拋出運行時錯誤之后,進行了回滾操作震放,并把異常宾毒,數(shù)據(jù)庫的數(shù)據(jù)并沒有更新


image

如果把拋出異常這步去掉,那么就可以正常更新數(shù)據(jù)了


image
image

總結(jié)

這種編程式的事務(wù)方法其實叫做基于 TransactionTemplate 的編程式事務(wù)管理殿遂,另外還有一種是基于底層 API 的編程式事務(wù)管理诈铛,他是利用了PlatformTransactionManager、TransactionDefinition 和 TransactionStatus 三個核心接口的API完成對事物的管理墨礁,不過本質(zhì)來說只是表現(xiàn)形式不同而已幢竹,換湯不換藥

3.2、聲明式事務(wù)

在真正的開發(fā)中恩静,如果需要管理的事務(wù)很多焕毫,使用編程式去硬編碼完成,一方面使得代碼耦合度提高了驶乾,另一方面再去修改成本也很大邑飒,維護難度提高了举娩,最好還是無侵入式的方法最好田绑,也就是我們現(xiàn)在所說的聲明式事務(wù),充分的使用spring的AOP功能媳友,具體的AOP學(xué)習(xí)可以看Spring AOP學(xué)習(xí)风科,當(dāng)然了按照spring的套路肯定提供了xml配置和注解兩種方法了撒轮。

3.2.1、TransactionInterceptor 方法

    <bean id="transactionInterceptor"
        class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

    <bean id="moneyServiceProxy"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="moneyService"/>
        <property name="interceptorNames">
            <list>
                <idref bean="transactionInterceptor"/>
            </list>
        </property>
    </bean>

在獲取bean的時候贼穆,獲取通過ProxyFactoryBean包裝好的moneyServiceProxy题山,其他不需要做任何操作

這里有一點需要主要的是,transactionInterceptor中的transactionAttributes屬性信息故痊,當(dāng)前demo中的key是"*",實際上有各種可配置的顶瞳,具體的配置是傳播行為 [,隔離級別] [愕秫,只讀屬性] [浊仆,超時屬性] [不影響提交的異常] [,導(dǎo)致回滾的異常]

  • 傳播行為就是上面所述的傳播行為的屬性豫领,隔離級別也是類似
  • 只讀屬性是readOnly字段
  • 超時屬性是必須以TIMEOUT_開頭,后面跟著一個數(shù)字舔琅,表示事務(wù)允許超時多少的最大表秒數(shù)
  • 不影響提交的異常是指出現(xiàn)該些異常等恐,事務(wù)正常提交,不會發(fā)生回滾,需要加上+课蔬,例如+RuntimeException
  • 導(dǎo)致回滾的異常是值出現(xiàn)該些異常囱稽,事務(wù)將會回滾,需要加上-二跋,例如-Exception

同樣的key中的表示方法名稱战惊,可以模糊匹配,如果是*則表示所有的函數(shù)都有事務(wù)扎即,例如key="change"吞获,則意味著只有change函數(shù)需要添加事務(wù)

3.2.2、TransactionProxyFactoryBean 方法

上述的TransactionInterceptor雖然實現(xiàn)了無侵入式的方法谚鄙,但是如果需要添加事務(wù)的類過多則就意味著所有的類都必須有這樣的配置各拷,spring提供了一個新的bean TransactionProxyFactoryBean,不過我個人覺得也沒改善太多闷营,就是把兩個bean的內(nèi)容組合到一起烤黍,減少了一些配置而已。

    <bean id="moneyServiceProxy2"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="target" ref="moneyService" />
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

在具體使用的使用傻盟,使用moneyServiceProxy2這個bean即可速蕊,如果仔細查看配置的話,確實和TransactionInterceptor沒有太多的區(qū)別

3.2.3娘赴、命名空間 方法

何所謂命名空間呢规哲,就是利用spring本身的包含的各種NamespaceHandler去解析處理各種自定義的xml標(biāo)簽,自動注入各種bean去完成相關(guān)任務(wù)筝闹,在spring中提供了tx以及aop實現(xiàn)該功能

    <tx:advice id="transAdvice" transaction-manager="transactionManager">
        <!--配置事務(wù)傳播性媳叨,隔離級別以及超時回滾等問題 -->
        <tx:attributes>
            <tx:method name="*" 
                propagation="REQUIRED"
                rollback-for="Exception" 
                timeout="10"
                read-only="true"
                isolation="DEFAULT"
                no-rollback-for="Exception" 
                <!-- 以上都是配置的屬性而已 -->
            />
        </tx:attributes>
    </tx:advice>
    
    <aop:config>
        <!--配置事務(wù)切點 -->
        <aop:pointcut id="services"
            expression="execution(* com.demo.jdbc.MoneyService.*(..))" />
        <aop:advisor pointcut-ref="services" advice-ref="transAdvice" />
    </aop:config>

先是設(shè)置了一些包含事務(wù)的方法,并且設(shè)置有傳遞行為关顷、隔離級別等屬性糊秆,然后利用AOP的切面功能去實現(xiàn)事務(wù)處理

3.2.4、Transactional 注解 方法

既然xml配置都已經(jīng)存在了议双,再支持注解的方法也是完全可以的

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    ...

可以支持在類上和方法上添加該注解痘番,如果再類上面則該類中的public方法都會被添加上具體的事務(wù)方法的,例如如下配置

@Transactional(propagation = Propagation.REQUIRED)
public void change() {
    moneyDao.update(1L, 30L);        
    test();
    moneyDao.update(2L, 120L);
}

還有個點別忘記了平痰,添加了注解還需要添加支持解析該注解的功能汞舱,在xml中添加上
<tx:annotation-driven transaction-manager="transactionManager"/>

4、總結(jié)

主要是介紹了事務(wù)的基本信息以及如何具體的使用事務(wù)宗雇,從本質(zhì)來說上面幾種方法沒有太多的差異昂芜,只是spring提供了更加便捷的方法去實現(xiàn)同樣的功能,后續(xù)會學(xué)習(xí)源碼層面赔蒲,了解spring如何實現(xiàn)該功能的泌神。以及異常如何被捕獲回滾操作良漱、冪等性的問題等還需要解決。

5欢际、參考鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末母市,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子损趋,更是在濱河造成了極大的恐慌患久,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浑槽,死亡現(xiàn)場離奇詭異蒋失,居然都是意外死亡,警方通過查閱死者的電腦和手機括荡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門高镐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人畸冲,你說我怎么就攤上這事嫉髓。” “怎么了邑闲?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵算行,是天一觀的道長。 經(jīng)常有香客問我苫耸,道長州邢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任褪子,我火速辦了婚禮量淌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嫌褪。我一直安慰自己呀枢,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布笼痛。 她就那樣靜靜地躺著裙秋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缨伊。 梳的紋絲不亂的頭發(fā)上摘刑,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天,我揣著相機與錄音刻坊,去河邊找鬼枷恕。 笑死,一個胖子當(dāng)著我的面吹牛谭胚,可吹牛的內(nèi)容都是我干的徐块。 我是一名探鬼主播隶校,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛹锰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起绰疤,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤铜犬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后轻庆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體癣猾,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年余爆,在試婚紗的時候發(fā)現(xiàn)自己被綠了纷宇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛾方,死狀恐怖像捶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桩砰,我是刑警寧澤拓春,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站亚隅,受9級特大地震影響硼莽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜煮纵,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一懂鸵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧行疏,春花似錦匆光、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至货葬,卻和暖如春采幌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背震桶。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工休傍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹲姐。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓磨取,卻偏偏與公主長得像人柿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子忙厌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,926評論 2 361

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理凫岖,服務(wù)發(fā)現(xiàn),斷路器逢净,智...
    卡卡羅2017閱讀 134,719評論 18 139
  • 很多人喜歡這篇文章哥放,特此同步過來 由淺入深談?wù)搒pring事務(wù) 前言 這篇其實也要歸納到《常識》系列中,但這重點又...
    碼農(nóng)戲碼閱讀 4,747評論 2 59
  • Spring 事務(wù)屬性分析 事務(wù)管理對于企業(yè)應(yīng)用而言至關(guān)重要爹土。它保證了用戶的每一次操作都是可靠的甥雕,即便出現(xiàn)了異常的...
    壹點零閱讀 1,306評論 0 2
  • spring,mybatis事務(wù)管理配置與@Transactional注解使用 概述 事務(wù)管理對于企業(yè)應(yīng)用來說是至...
    tenlee閱讀 4,191評論 0 11
  • 這真不是一個廣告。 這個必須先說明一下胀茵,因為昨天獲得點贊最高的是什么值得買社露。 什么值得買: 1、什么值得買是高大上...
    英文秀閱讀 562評論 0 3