帶你讀懂Spring 事務(wù)——事務(wù)的傳播機(jī)制(藏)

不了解事務(wù)的先看上一篇:帶你讀懂Spring 事務(wù)——認(rèn)識(shí)事務(wù)

一因悲、什么是事務(wù)的傳播?

簡(jiǎn)單的理解就是多個(gè)事務(wù)方法相互調(diào)用時(shí),事務(wù)如何在這些方法間傳播。

舉個(gè)栗子,方法A是一個(gè)事務(wù)的方法冀偶,方法A執(zhí)行過(guò)程中調(diào)用了方法B,那么方法B有無(wú)事務(wù)以及方法B對(duì)事務(wù)的要求不同都會(huì)對(duì)方法A的事務(wù)具體執(zhí)行造成影響渔嚷,同時(shí)方法A的事務(wù)對(duì)方法B的事務(wù)執(zhí)行也有影響进鸠,這種影響具體是什么就由兩個(gè)方法所定義的事務(wù)傳播類(lèi)型所決定。

二形病、Spring事務(wù)傳播類(lèi)型枚舉Propagation介紹

在Spring中對(duì)于事務(wù)的傳播行為定義了七種類(lèi)型分別是:REQUIRED客年、SUPPORTS、MANDATORY漠吻、REQUIRES_NEW量瓜、NOT_SUPPORTED、NEVER途乃、NESTED绍傲。

在Spring源碼中這七種類(lèi)型被定義為了枚舉。源碼在org.springframework.transaction.annotation包下的Propagation耍共,源碼中注釋很多烫饼,對(duì)傳播行為的七種類(lèi)型的不同含義都有解釋,后文中錘子我也會(huì)給大家分析试读,我在這里就不貼所有的源碼杠纵,只把這個(gè)類(lèi)上的注解貼一下,翻譯一下就是:表示與TransactionDefinition接口相對(duì)應(yīng)的用于@Transactional注解的事務(wù)傳播行為的枚舉钩骇。

也就是說(shuō)枚舉類(lèi)Propagation是為了結(jié)合@Transactional注解使用而設(shè)計(jì)的比藻,這個(gè)枚舉里面定義的事務(wù)傳播行為類(lèi)型與TransactionDefinition中定義的事務(wù)傳播行為類(lèi)型是對(duì)應(yīng)的,所以在使用@Transactional注解時(shí)我們就要使用Propagation枚舉類(lèi)來(lái)指定傳播行為類(lèi)型倘屹,而不直接使用TransactionDefinition接口里定義的屬性银亲。

在TransactionDefinition接口中定義了Spring事務(wù)的一些屬性,不僅包括事務(wù)傳播特性類(lèi)型纽匙,還包括了事務(wù)的隔離級(jí)別類(lèi)型(事務(wù)的隔離級(jí)別后面文章會(huì)詳細(xì)講解)务蝠,更多詳細(xì)信息,大家可以打開(kāi)源碼自己翻譯一下里面的注釋


package org.springframework.transaction.annotation;

import org.springframework.transaction.TransactionDefinition;

/**
 * Enumeration that represents transaction propagation behaviors for use
 * with the {@link Transactional} annotation, corresponding to the
 * {@link TransactionDefinition} interface.
 *
 * @author Colin Sampaleanu
 * @author Juergen Hoeller
 * @since 1.2
 */
public enum Propagation {
    ...
}

三哄辣、七種事務(wù)傳播行為詳解與示例

在介紹七種事務(wù)傳播行為前请梢,我們先設(shè)計(jì)一個(gè)場(chǎng)景,幫助大家理解力穗,場(chǎng)景描述如下

現(xiàn)有兩個(gè)方法A和B毅弧,方法A執(zhí)行會(huì)在數(shù)據(jù)庫(kù)ATable插入一條數(shù)據(jù),方法B執(zhí)行會(huì)在數(shù)據(jù)庫(kù)BTable插入一條數(shù)據(jù)当窗,偽代碼如下:

//將傳入?yún)?shù)a存入ATable
pubilc void A(a){
    insertIntoATable(a);    
}
//將傳入?yún)?shù)b存入BTable
public void B(b){
    insertIntoBTable(b);
}

接下來(lái)够坐,我們看看在如下場(chǎng)景下,沒(méi)有事務(wù),情況會(huì)怎樣


public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
}

public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    throw Exception;     //發(fā)生異常拋出
    B(b2);  //調(diào)用B入?yún)2
}

在這里要做一個(gè)重要提示:Spring中事務(wù)的默認(rèn)實(shí)現(xiàn)使用的是AOP元咙,也就是代理的方式梯影,如果大家在使用代碼測(cè)試時(shí),同一個(gè)Service類(lèi)中的方法相互調(diào)用需要使用注入的對(duì)象來(lái)調(diào)用庶香,不要直接使用this.方法名來(lái)調(diào)用甲棍,this.方法名調(diào)用是對(duì)象內(nèi)部方法調(diào)用,不會(huì)通過(guò)Spring代理赶掖,也就是事務(wù)不會(huì)起作用

以上偽代碼描述的一個(gè)場(chǎng)景感猛,方法testMain和testB都沒(méi)有事務(wù),執(zhí)行testMain方法奢赂,那么結(jié)果會(huì)怎么樣呢陪白?

相信大家都知道了,就是a1數(shù)據(jù)成功存入ATable表膳灶,b1數(shù)據(jù)成功存入BTable表咱士,而在拋出異常后b2數(shù)據(jù)存儲(chǔ)就不會(huì)執(zhí)行,也就是b2數(shù)據(jù)不會(huì)存入數(shù)據(jù)庫(kù)轧钓,這就是沒(méi)有事務(wù)的場(chǎng)景序厉。

可想而知,在上一篇文章(認(rèn)識(shí)事務(wù))中舉例的轉(zhuǎn)賬操作聋迎,如果在某一步發(fā)生異常脂矫,且沒(méi)有事務(wù),那么錢(qián)是不是就憑空消失了霉晕,所以事務(wù)在數(shù)據(jù)庫(kù)操作中的重要性可想而知。接下我們就開(kāi)始理解七種不同事務(wù)傳播類(lèi)型的含義

REQUIRED(Spring默認(rèn)的事務(wù)傳播類(lèi)型)

如果當(dāng)前沒(méi)有事務(wù)捞奕,則自己新建一個(gè)事務(wù)牺堰,如果當(dāng)前存在事務(wù),則加入這個(gè)事務(wù)

源碼說(shuō)明如下:


    /**
     * Support a current transaction, create a new one if none exists.
     * Analogous to EJB transaction attribute of the same name.
     * <p>This is the default setting of a transaction annotation.
     */
    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

(示例1)根據(jù)場(chǎng)景舉栗子,我們?cè)趖estMain和testB上聲明事務(wù)颅围,設(shè)置傳播行為REQUIRED伟葫,偽代碼如下:


@Transactional(propagation = Propagation.REQUIRED)
public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
}
@Transactional(propagation = Propagation.REQUIRED)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    throw Exception;     //發(fā)生異常拋出
    B(b2);  //調(diào)用B入?yún)2
}

該場(chǎng)景下執(zhí)行testMain方法結(jié)果如何呢?

數(shù)據(jù)庫(kù)沒(méi)有插入新的數(shù)據(jù)院促,數(shù)據(jù)庫(kù)還是保持著執(zhí)行testMain方法之前的狀態(tài)筏养,沒(méi)有發(fā)生改變。testMain上聲明了事務(wù)常拓,在執(zhí)行testB方法時(shí)就加入了testMain的事務(wù)(當(dāng)前存在事務(wù)渐溶,則加入這個(gè)事務(wù)),在執(zhí)行testB方法拋出異常后事務(wù)會(huì)發(fā)生回滾弄抬,又testMain和testB使用的同一個(gè)事務(wù)茎辐,所以事務(wù)回滾后testMain和testB中的操作都會(huì)回滾,也就使得數(shù)據(jù)庫(kù)仍然保持初始狀態(tài)

(示例2)根據(jù)場(chǎng)景再舉一個(gè)栗子,我們只在testB上聲明事務(wù),設(shè)置傳播行為REQUIRED拖陆,偽代碼如下:


public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
}
@Transactional(propagation = Propagation.REQUIRED)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    throw Exception;     //發(fā)生異常拋出
    B(b2);  //調(diào)用B入?yún)2
}

這時(shí)的執(zhí)行結(jié)果又如何呢弛槐?

數(shù)據(jù)a1存儲(chǔ)成功,數(shù)據(jù)b1和b2沒(méi)有存儲(chǔ)依啰。由于testMain沒(méi)有聲明事務(wù)乎串,testB有聲明事務(wù)且傳播行為是REQUIRED,所以在執(zhí)行testB時(shí)會(huì)自己新建一個(gè)事務(wù)(如果當(dāng)前沒(méi)有事務(wù)速警,則自己新建一個(gè)事務(wù))叹誉,testB拋出異常則只有testB中的操作發(fā)生了回滾,也就是b1的存儲(chǔ)會(huì)發(fā)生回滾坏瞄,但a1數(shù)據(jù)不會(huì)回滾桂对,所以最終a1數(shù)據(jù)存儲(chǔ)成功,b1和b2數(shù)據(jù)沒(méi)有存儲(chǔ)

SUPPORTS

當(dāng)前存在事務(wù)鸠匀,則加入當(dāng)前事務(wù)蕉斜,如果當(dāng)前沒(méi)有事務(wù),就以非事務(wù)方法執(zhí)行

源碼注釋如下(太長(zhǎng)省略了一部分)缀棍,其中里面有一個(gè)提醒翻譯一下就是:“對(duì)于具有事務(wù)同步的事務(wù)管理器宅此,SUPPORTS與完全沒(méi)有事務(wù)稍有不同,因?yàn)樗x了可能應(yīng)用同步的事務(wù)范圍”爬范。這個(gè)是與事務(wù)同步管理器相關(guān)的一個(gè)注意項(xiàng)父腕,這里不過(guò)多討論。


    /**
     * Support a current transaction, execute non-transactionally if none exists.
     * Analogous to EJB transaction attribute of the same name.
     * <p>Note: For transaction managers with transaction synchronization,
     * {@code SUPPORTS} is slightly different from no transaction at all,
     * as it defines a transaction scope that synchronization will apply for.
     ...
     */
    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

(示例3)根據(jù)場(chǎng)景舉栗子青瀑,我們只在testB上聲明事務(wù)璧亮,設(shè)置傳播行為SUPPORTS,偽代碼如下:


public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
}
@Transactional(propagation = Propagation.SUPPORTS)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    throw Exception;     //發(fā)生異常拋出
    B(b2);  //調(diào)用B入?yún)2
}

這種情況下斥难,執(zhí)行testMain的最終結(jié)果就是枝嘶,a1,b1存入數(shù)據(jù)庫(kù)哑诊,b2沒(méi)有存入數(shù)據(jù)庫(kù)群扶。由于testMain沒(méi)有聲明事務(wù),且testB的事務(wù)傳播行為是SUPPORTS镀裤,所以執(zhí)行testB時(shí)就是沒(méi)有事務(wù)的(如果當(dāng)前沒(méi)有事務(wù)竞阐,就以非事務(wù)方法執(zhí)行),則在testB拋出異常時(shí)也不會(huì)發(fā)生回滾暑劝,所以最終結(jié)果就是a1和b1存儲(chǔ)成功骆莹,b2沒(méi)有存儲(chǔ)。

那么當(dāng)我們?cè)趖estMain上聲明事務(wù)且使用REQUIRED傳播方式的時(shí)候铃岔,這個(gè)時(shí)候執(zhí)行testB就滿足當(dāng)前存在事務(wù)汪疮,則加入當(dāng)前事務(wù)峭火,在testB拋出異常時(shí)事務(wù)就會(huì)回滾,最終結(jié)果就是a1智嚷,b1和b2都不會(huì)存儲(chǔ)到數(shù)據(jù)庫(kù)

MANDATORY

當(dāng)前存在事務(wù)卖丸,則加入當(dāng)前事務(wù),如果當(dāng)前事務(wù)不存在盏道,則拋出異常稍浆。

源碼注釋如下:


    /**
     * Support a current transaction, throw an exception if none exists.
     * Analogous to EJB transaction attribute of the same name.
     */
    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

(示例4)場(chǎng)景舉栗子,我們只在testB上聲明事務(wù)猜嘱,設(shè)置傳播行為MANDATORY衅枫,偽代碼如下:


public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
}
@Transactional(propagation = Propagation.MANDATORY)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    throw Exception;     //發(fā)生異常拋出
    B(b2);  //調(diào)用B入?yún)2
}

這種情形的執(zhí)行結(jié)果就是a1存儲(chǔ)成功,而b1和b2沒(méi)有存儲(chǔ)朗伶。b1和b2沒(méi)有存儲(chǔ)弦撩,并不是事務(wù)回滾的原因,而是因?yàn)閠estMain方法沒(méi)有聲明事務(wù)论皆,在去執(zhí)行testB方法時(shí)就直接拋出事務(wù)要求的異常(如果當(dāng)前事務(wù)不存在益楼,則拋出異常),所以testB方法里的內(nèi)容就沒(méi)有執(zhí)行点晴。

那么如果在testMain方法進(jìn)行事務(wù)聲明感凤,并且設(shè)置為REQUIRED,則執(zhí)行testB時(shí)就會(huì)使用testMain已經(jīng)開(kāi)啟的事務(wù)粒督,遇到異常就正常的回滾了陪竿。

REQUIRES_NEW

創(chuàng)建一個(gè)新事務(wù),如果存在當(dāng)前事務(wù)屠橄,則掛起該事務(wù)族跛。

可以理解為設(shè)置事務(wù)傳播類(lèi)型為REQUIRES_NEW的方法,在執(zhí)行時(shí)锐墙,不論當(dāng)前是否存在事務(wù)庸蔼,總是會(huì)新建一個(gè)事務(wù)。

源碼注釋如下


    /**
     * Create a new transaction, and suspend the current transaction if one exists.
     ...
     */
    REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

(示例5)場(chǎng)景舉栗子贮匕,為了說(shuō)明設(shè)置REQUIRES_NEW的方法會(huì)開(kāi)啟新事務(wù),我們把異常發(fā)生的位置換到了testMain花枫,然后給testMain聲明事務(wù)刻盐,傳播類(lèi)型設(shè)置為REQUIRED,testB也聲明事務(wù)劳翰,設(shè)置傳播類(lèi)型為REQUIRES_NEW敦锌,偽代碼如下

@Transactional(propagation = Propagation.REQUIRED)
public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
    throw Exception;     //發(fā)生異常拋出
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    B(b2);  //調(diào)用B入?yún)2
}

這種情形的執(zhí)行結(jié)果就是a1沒(méi)有存儲(chǔ),而b1和b2存儲(chǔ)成功佳簸,因?yàn)閠estB的事務(wù)傳播設(shè)置為REQUIRES_NEW,所以在執(zhí)行testB時(shí)會(huì)開(kāi)啟一個(gè)新的事務(wù)乙墙,testMain中發(fā)生的異常時(shí)在testMain所開(kāi)啟的事務(wù)中颖变,所以這個(gè)異常不會(huì)影響testB的事務(wù)提交,testMain中的事務(wù)會(huì)發(fā)生回滾听想,所以最終a1就沒(méi)有存儲(chǔ)腥刹,而b1和b2就存儲(chǔ)成功了。

與這個(gè)場(chǎng)景對(duì)比的一個(gè)場(chǎng)景就是testMain和testB都設(shè)置為REQUIRED汉买,那么上面的代碼執(zhí)行結(jié)果就是所有數(shù)據(jù)都不會(huì)存儲(chǔ)衔峰,因?yàn)閠estMain和testMain是在同一個(gè)事務(wù)下的,所以事務(wù)發(fā)生回滾時(shí)蛙粘,所有的數(shù)據(jù)都會(huì)回滾

NOT_SUPPORTED

始終以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù)垫卤,則掛起當(dāng)前事務(wù)

可以理解為設(shè)置事務(wù)傳播類(lèi)型為NOT_SUPPORTED的方法,在執(zhí)行時(shí)出牧,不論當(dāng)前是否存在事務(wù)穴肘,都會(huì)以非事務(wù)的方式運(yùn)行。

源碼說(shuō)明如下


/**
     * Execute non-transactionally, suspend the current transaction if one exists.
     ...
     */
    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

(示例6)場(chǎng)景舉栗子舔痕,testMain傳播類(lèi)型設(shè)置為REQUIRED评抚,testB傳播類(lèi)型設(shè)置為NOT_SUPPORTED,且異常拋出位置在testB中赵讯,偽代碼如下

@Transactional(propagation = Propagation.REQUIRED)
public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    throw Exception;     //發(fā)生異常拋出
    B(b2);  //調(diào)用B入?yún)2
}

該場(chǎng)景的執(zhí)行結(jié)果就是a1和b2沒(méi)有存儲(chǔ)盈咳,而b1存儲(chǔ)成功。testMain有事務(wù)边翼,而testB不使用事務(wù)鱼响,所以執(zhí)行中testB的存儲(chǔ)b1成功,然后拋出異常组底,此時(shí)testMain檢測(cè)到異常事務(wù)發(fā)生回滾丈积,但是由于testB不在事務(wù)中,所以只有testMain的存儲(chǔ)a1發(fā)生了回滾债鸡,最終只有b1存儲(chǔ)成功江滨,而a1和b1都沒(méi)有存儲(chǔ)

NEVER

不使用事務(wù),如果當(dāng)前事務(wù)存在厌均,則拋出異常

很容易理解唬滑,就是我這個(gè)方法不使用事務(wù),并且調(diào)用我的方法也不允許有事務(wù)棺弊,如果調(diào)用我的方法有事務(wù)則我直接拋出異常晶密。

源碼注釋如下:


    /**
     * Execute non-transactionally, throw an exception if a transaction exists.
     * Analogous to EJB transaction attribute of the same name.
     */
    NEVER(TransactionDefinition.PROPAGATION_NEVER),

(示例7)場(chǎng)景舉栗子,testMain設(shè)置傳播類(lèi)型為REQUIRED模她,testB傳播類(lèi)型設(shè)置為NEVER稻艰,并且把testB中的拋出異常代碼去掉,則偽代碼如下

@Transactional(propagation = Propagation.REQUIRED)
public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
}
@Transactional(propagation = Propagation.NEVER)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    B(b2);  //調(diào)用B入?yún)2
}

該場(chǎng)景執(zhí)行侈净,直接拋出事務(wù)異常尊勿,且不會(huì)有數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)僧凤。由于testMain事務(wù)傳播類(lèi)型為REQUIRED,所以testMain是運(yùn)行在事務(wù)中元扔,而testB事務(wù)傳播類(lèi)型為NEVER躯保,所以testB不會(huì)執(zhí)行而是直接拋出事務(wù)異常,此時(shí)testMain檢測(cè)到異常就發(fā)生了回滾摇展,所以最終數(shù)據(jù)庫(kù)不會(huì)有數(shù)據(jù)存入吻氧。

NESTED

如果當(dāng)前事務(wù)存在,則在嵌套事務(wù)中執(zhí)行咏连,否則REQUIRED的操作一樣(開(kāi)啟一個(gè)事務(wù))

這里需要注意兩點(diǎn):

  • 和REQUIRES_NEW的區(qū)別

REQUIRES_NEW是新建一個(gè)事務(wù)并且新開(kāi)啟的這個(gè)事務(wù)與原有事務(wù)無(wú)關(guān)盯孙,而NESTED則是當(dāng)前存在事務(wù)時(shí)(我們把當(dāng)前事務(wù)稱之為父事務(wù))會(huì)開(kāi)啟一個(gè)嵌套事務(wù)(稱之為一個(gè)子事務(wù))。
在NESTED情況下父事務(wù)回滾時(shí)祟滴,子事務(wù)也會(huì)回滾振惰,而在REQUIRES_NEW情況下,原有事務(wù)回滾垄懂,不會(huì)影響新開(kāi)啟的事務(wù)骑晶。

  • 和REQUIRED的區(qū)別

REQUIRED情況下,調(diào)用方存在事務(wù)時(shí)草慧,則被調(diào)用方和調(diào)用方使用同一事務(wù)桶蛔,那么被調(diào)用方出現(xiàn)異常時(shí),由于共用一個(gè)事務(wù)漫谷,所以無(wú)論調(diào)用方是否catch其異常仔雷,事務(wù)都會(huì)回滾
而在NESTED情況下,被調(diào)用方發(fā)生異常時(shí)舔示,調(diào)用方可以catch其異常碟婆,這樣只有子事務(wù)回滾,父事務(wù)不受影響

(示例8)場(chǎng)景舉栗子惕稻,testMain設(shè)置為REQUIRED竖共,testB設(shè)置為NESTED,且異常發(fā)生在testMain中俺祠,偽代碼如下

@Transactional(propagation = Propagation.REQUIRED)
public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    testB();    //調(diào)用testB
    throw Exception;     //發(fā)生異常拋出
}
@Transactional(propagation = Propagation.NEVER)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    B(b2);  //調(diào)用B入?yún)2
}

該場(chǎng)景下公给,所有數(shù)據(jù)都不會(huì)存入數(shù)據(jù)庫(kù),因?yàn)樵趖estMain發(fā)生異常時(shí)蜘渣,父事務(wù)回滾則子事務(wù)也跟著回滾了妓布,可以與(示例5)比較看一下,就找出了與REQUIRES_NEW的不同

(示例9)場(chǎng)景舉栗子宋梧,testMain設(shè)置為REQUIRED,testB設(shè)置為NESTED狰挡,且異常發(fā)生在testB中捂龄,偽代碼如下

@Transactional(propagation = Propagation.REQUIRED)
public void testMain(){
    A(a1);  //調(diào)用A入?yún)1
    try{
        testB();    //調(diào)用testB
    }catch(Exception e){
        
    }
    A(a2);
}
@Transactional(propagation = Propagation.NEVER)
public void testB(){
    B(b1);  //調(diào)用B入?yún)1
    throw Exception;     //發(fā)生異常拋出
    B(b2);  //調(diào)用B入?yún)2
}

這種場(chǎng)景下释涛,結(jié)果是a1,a2存儲(chǔ)成功,b1和b2存儲(chǔ)失敗倦沧,因?yàn)檎{(diào)用方catch了被調(diào)方的異常唇撬,所以只有子事務(wù)回滾了。

同樣的代碼展融,如果我們把testB的傳播類(lèi)型改為REQUIRED窖认,結(jié)果也就變成了:沒(méi)有數(shù)據(jù)存儲(chǔ)成功。就算在調(diào)用方catch了異常告希,整個(gè)事務(wù)還是會(huì)回滾扑浸,因?yàn)檠嗯迹{(diào)用方和被調(diào)方共用的同一個(gè)事務(wù)

文章歡迎轉(zhuǎn)載酝惧,轉(zhuǎn)載請(qǐng)注明出處盗似,個(gè)人公眾號(hào)【愛(ài)做夢(mèng)的錘子】萌踱,全網(wǎng)同id,個(gè)站 http://te-amo.site园担,歡迎關(guān)注湖雹,里面會(huì)分享更多有用知識(shí)纵装,還有我的私密照片

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挽唉,一起剝皮案震驚了整個(gè)濱河市桑逝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌糙俗,老刑警劉巖格二,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡冬骚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)唉韭,“玉大人夜涕,你說(shuō)我怎么就攤上這事∈舴撸” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵酸役,是天一觀的道長(zhǎng)住诸。 經(jīng)常有香客問(wèn)我,道長(zhǎng)涣澡,這世上最難降的妖魔是什么贱呐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮入桂,結(jié)果婚禮上奄薇,老公的妹妹穿的比我還像新娘。我一直安慰自己抗愁,他們只是感情好馁蒂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蜘腌,像睡著了一般沫屡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撮珠,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天沮脖,我揣著相機(jī)與錄音,去河邊找鬼芯急。 笑死勺届,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的娶耍。 我是一名探鬼主播免姿,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伺绽!你這毒婦竟也來(lái)了养泡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤奈应,失蹤者是張志新(化名)和其女友劉穎澜掩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體杖挣,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肩榕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片株汉。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筐乳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乔妈,到底是詐尸還是另有隱情蝙云,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布路召,位于F島的核電站勃刨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏股淡。R本人自食惡果不足惜身隐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望唯灵。 院中可真熱鬧贾铝,春花似錦、人聲如沸埠帕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)搞监。三九已至水孩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間琐驴,已是汗流浹背俘种。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绝淡,地道東北人宙刘。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像牢酵,于是被迫代替她去往敵國(guó)和親悬包。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354