Spring事務(wù)

事務(wù)的嵌套概念

所謂事務(wù)的嵌套就是兩個(gè)事務(wù)方法之間相互調(diào)用初厚。spring事務(wù)開啟 ,或者是基于接口的或者是基于類的代理被創(chuàng)建(注意一定要是代理,不能手動(dòng)new 一個(gè)對(duì)象产禾,并且此類(有無接口都行)一定要被代理——spring中的bean只要納入了IOC管理都是被代理的)排作。所以在同一個(gè)類中一個(gè)方法調(diào)用另一個(gè)方法有事務(wù)的方法,事務(wù)是不會(huì)起作用的亚情。

事務(wù)異惩荆回滾

Spring默認(rèn)情況下會(huì)對(duì)運(yùn)行期例外(RunTimeException),即uncheck異常楞件,進(jìn)行事務(wù)回滾衫生。
如果遇到checked異常就不回滾。

如何改變默認(rèn)規(guī)則

  1. 讓checked例外也回滾:在整個(gè)方法前加上 @Transactional(rollbackFor=Exception.class)
  1. 讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)
  1. 不需要事務(wù)管理的(只查詢的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)
    上面三種方式也可在xml配置

spring事務(wù)傳播屬性

在 spring的 TransactionDefinition接口中一共定義了六種事務(wù)傳播屬性:

  • PROPAGATION_REQUIRED -- 支持當(dāng)前事務(wù)土浸,如果當(dāng)前沒有事務(wù)罪针,就新建一個(gè)事務(wù)。這是最常見的選擇黄伊。

  • PROPAGATION_SUPPORTS -- 支持當(dāng)前事務(wù)泪酱,如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行还最。

  • PROPAGATION_MANDATORY -- 支持當(dāng)前事務(wù)墓阀,如果當(dāng)前沒有事務(wù),就拋出異常拓轻。

  • PROPAGATION_REQUIRES_NEW -- 新建事務(wù)斯撮,如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起扶叉。

  • PROPAGATION_NOT_SUPPORTED -- 以非事務(wù)方式執(zhí)行操作吮成,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起辜梳。

  • PROPAGATION_NEVER -- 以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù)泳叠,則拋出異常作瞄。

  • PROPAGATION_NESTED -- 如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行危纫。如果當(dāng)前沒有事務(wù)宗挥,則進(jìn)行與PROPAGATION_REQUIRED類似的操作。

前六個(gè)策略類似于EJB CMT种蝶,第七個(gè)(PROPAGATION_NESTED)是Spring所提供的一個(gè)特殊變量契耿。

它要求事務(wù)管理器或者使用JDBC 3.0 Savepoint API提供嵌套事務(wù)行為(如Spring的DataSourceTransactionManager)

舉例淺析Spring嵌套事務(wù)

ServiceA {  
         
     void methodA() {  
         ServiceB.methodB();  
     }  
    
}  
    
ServiceB {  
         
     void methodB() {  
     }  
         
}  
1、PROPAGATION_REQUIRED

假如當(dāng)前正要執(zhí)行的事務(wù)不在另外一個(gè)事務(wù)里螃征,那么就起一個(gè)新的事務(wù)
比如說搪桂,ServiceB.methodB的事務(wù)級(jí)別定義為PROPAGATION_REQUIRED, 那么由于執(zhí)行ServiceA.methodA的時(shí)候
(1)、如果ServiceA.methodA已經(jīng)起了事務(wù),這時(shí)調(diào)用ServiceB.methodB踢械,ServiceB.methodB看到自己已經(jīng)運(yùn)行在ServiceA.methodA的事務(wù)內(nèi)部酗电,就不再起新的事務(wù)。這時(shí)只有外部事務(wù)并且他們是共用的内列,所以這時(shí)ServiceA.methodA或者ServiceB.methodB無論哪個(gè)發(fā)生異常methodA和methodB作為一個(gè)整體都將一起回滾撵术。
(2)、如果ServiceA.methodA沒有事務(wù)话瞧,ServiceB.methodB就會(huì)為自己分配一個(gè)事務(wù)嫩与。這樣,在ServiceA.methodA中是沒有事務(wù)控制的交排。只是在ServiceB.methodB內(nèi)的任何地方出現(xiàn)異常划滋,ServiceB.methodB將會(huì)被回滾,不會(huì)引起ServiceA.methodA的回滾

2个粱、PROPAGATION_SUPPORTS

如果當(dāng)前在事務(wù)中古毛,即以事務(wù)的形式運(yùn)行,如果當(dāng)前不再一個(gè)事務(wù)中都许,那么就以非事務(wù)的形式運(yùn)行 稻薇。

3、PROPAGATION_MANDATORY

必須在一個(gè)事務(wù)中運(yùn)行胶征。也就是說塞椎,他只能被一個(gè)父事務(wù)調(diào)用。否則睛低,他就要拋出異常

4案狠、PROPAGATION_REQUIRES_NEW

啟動(dòng)一個(gè)新的, 不依賴于環(huán)境的 "內(nèi)部" 事務(wù). 這個(gè)事務(wù)將被完全 commited 或 rolled back 而不依賴于外部事務(wù), 它擁有自己的隔離范圍, 自己的鎖, 等等. 當(dāng)內(nèi)部事務(wù)開始執(zhí)行時(shí), 外部事務(wù)將被掛起, 內(nèi)務(wù)事務(wù)結(jié)束時(shí), 外部事務(wù)將繼續(xù)執(zhí)行.
比如我們?cè)O(shè)計(jì)ServiceA.methodA的事務(wù)級(jí)別為PROPAGATION_REQUIRED,ServiceB.methodB的事務(wù)級(jí)別為PROPAGATION_REQUIRES_NEW钱雷,那么當(dāng)執(zhí)行到ServiceB.methodB的時(shí)候骂铁,ServiceA.methodA所在的事務(wù)就會(huì)掛起,ServiceB.methodB會(huì)起一個(gè)新的事務(wù)罩抗,等待ServiceB.methodB的事務(wù)完成以后拉庵,他才繼續(xù)執(zhí)行。他與PROPAGATION_REQUIRED 的事務(wù)區(qū)別在于事務(wù)的回滾程度了套蒂。因?yàn)镾erviceB.methodB是新起一個(gè)事務(wù)钞支,那么就是存在兩個(gè)不同的事務(wù)。
(1)操刀、如果ServiceB.methodB已經(jīng)提交烁挟,那么ServiceA.methodA失敗回滾,ServiceB.methodB是不會(huì)回滾的骨坑。
(2)撼嗓、如果ServiceB.methodB失敗回滾,如果他拋出的異常被ServiceA.methodA的try..catch捕獲并處理,ServiceA.methodA事務(wù)仍然可能提交静稻;如果他拋出的異常未被ServiceA.methodA捕獲處理警没,ServiceA.methodA事務(wù)將回滾。

場(chǎng)景: 不管業(yè)務(wù)邏輯的service是否有異常振湾,Log Service都應(yīng)該能夠記錄成功杀迹,所以Log Service的傳播屬性可以配為此屬性。最下面將會(huì)貼出配置代碼押搪。

5树酪、PROPAGATION_NOT_SUPPORTED

當(dāng)前不支持事務(wù)。比如ServiceA.methodA的事務(wù)級(jí)別是PROPAGATION_REQUIRED 大州,而ServiceB.methodB的事務(wù)級(jí)別是PROPAGATION_NOT_SUPPORTED 续语,那么當(dāng)執(zhí)行到ServiceB.methodB時(shí),ServiceA.methodA的事務(wù)掛起厦画,而他以非事務(wù)的狀態(tài)運(yùn)行完疮茄,再繼續(xù)ServiceA.methodA的事務(wù)。

6根暑、PROPAGATION_NEVER

不能在事務(wù)中運(yùn)行力试。假設(shè)ServiceA.methodA的事務(wù)級(jí)別是PROPAGATION_REQUIRED, 而ServiceB.methodB的事務(wù)級(jí)別是PROPAGATION_NEVER 排嫌,那么ServiceB.methodB就要拋出異常了畸裳。

7、PROPAGATION_NESTED (特殊)

開始一個(gè) "嵌套的" 事務(wù), 它是已經(jīng)存在事務(wù)的一個(gè)真正的子事務(wù). 潛套事務(wù)開始執(zhí)行時(shí), 它將取得一個(gè) savepoint. 如果這個(gè)嵌套事務(wù)失敗, 我們將回滾到此 savepoint. 潛套事務(wù)是外部事務(wù)的一部分, 只有外部事務(wù)結(jié)束后它才會(huì)被提交.

比如我們?cè)O(shè)計(jì)ServiceA.methodA的事務(wù)級(jí)別為PROPAGATION_REQUIRED淳地,ServiceB.methodB的事務(wù)級(jí)別為PROPAGATION_NESTED怖糊,那么當(dāng)執(zhí)行到ServiceB.methodB的時(shí)候,ServiceA.methodA所在的事務(wù)就會(huì)掛起颇象,ServiceB.methodB會(huì)起一個(gè)新的子事務(wù)并設(shè)置savepoint伍伤,等待ServiceB.methodB的事務(wù)完成以后,他才繼續(xù)執(zhí)行遣钳。嚷缭。因?yàn)镾erviceB.methodB是外部事務(wù)的子事務(wù),那么

1耍贾、如果ServiceB.methodB已經(jīng)提交,那么ServiceA.methodA失敗回滾路幸,ServiceB.methodB也將回滾荐开。

2、如果ServiceB.methodB失敗回滾简肴,如果他拋出的異常被ServiceA.methodA的try..catch捕獲并處理晃听,ServiceA.methodA事務(wù)仍然可能提交;如果他拋出的異常未被ServiceA.methodA捕獲處理,ServiceA.methodA事務(wù)將回滾能扒。

理解Nested的關(guān)鍵是savepoint佣渴。他與PROPAGATION_REQUIRES_NEW的區(qū)別是:

PROPAGATION_REQUIRES_NEW 完全是一個(gè)新的事務(wù),它與外部事務(wù)相互獨(dú)立; 而 PROPAGATION_NESTED 則是外部事務(wù)的子事務(wù), 如果外部事務(wù) commit, 嵌套事務(wù)也會(huì)被 commit, 這個(gè)規(guī)則同樣適用于 roll back.

 在 spring 中使用 PROPAGATION_NESTED的前提:

 1. 我們要設(shè)置 transactionManager 的 nestedTransactionAllowed 屬性為 true, 注意, 此屬性默認(rèn)為 false!!! 

 2. java.sql.Savepoint 必須存在, 即 jdk 版本要 1.4+ 

 3. Connection.getMetaData().supportsSavepoints() 必須為 true, 即 jdbc drive 必須支持 JDBC 3.0 

確保以上條件都滿足后, 你就可以嘗試使用 PROPAGATION_NESTED 了.


隔離級(jí)別(Isolation Level)

1初斑、Serializable:最嚴(yán)格的級(jí)別辛润,事務(wù)串行執(zhí)行,資源消耗最大见秤;

2砂竖、REPEATABLE READ:保證了一個(gè)事務(wù)不會(huì)修改已經(jīng)由另一個(gè)事務(wù)讀取但未提交(回滾)的數(shù)據(jù)。避免了“臟讀取”和“不可重復(fù)讀取”的情況鹃答,但是帶來了更多的性能損失乎澄。

3、READ COMMITTED:大多數(shù)主流數(shù)據(jù)庫的默認(rèn)事務(wù)等級(jí)测摔,保證了一個(gè)事務(wù)不會(huì)讀到另一個(gè)并行事務(wù)已修改但未提交的數(shù)據(jù)置济,避免了“臟讀取”。該級(jí)別適用于大多數(shù)系統(tǒng)锋八。

4浙于、Read Uncommitted:保證了讀取過程中不會(huì)讀取到非法數(shù)據(jù)。隔離級(jí)別在于處理多事務(wù)的并發(fā)問題查库。

我們知道并行可以提高數(shù)據(jù)庫的吞吐量和效率路媚,但是并不是所有的并發(fā)事務(wù)都可以并發(fā)運(yùn)行,這需要查看數(shù)據(jù)庫教材的可串行化條件判斷了樊销。

我們首先說并發(fā)中可能發(fā)生的3中不討人喜歡的事情

1: Dirty reads--讀臟數(shù)據(jù)整慎。也就是說,比如事務(wù)A的未提交(還依然緩存)的數(shù)據(jù)被事務(wù)B讀走围苫,如果事務(wù)A失敗回滾裤园,會(huì)導(dǎo)致事務(wù)B所讀取的的數(shù)據(jù)是錯(cuò)誤的。

2: non-repeatable reads--數(shù)據(jù)不可重復(fù)讀剂府。比如事務(wù)A中兩處讀取數(shù)據(jù)-total-的值拧揽。在第一讀的時(shí)候,total是100腺占,然后事務(wù)B就把total的數(shù)據(jù)改成 200淤袜,事務(wù)A再讀一次,結(jié)果就發(fā)現(xiàn)衰伯,total竟然就變成200了铡羡,造成事務(wù)A數(shù)據(jù)混亂。

3: phantom reads--幻象讀數(shù)據(jù)意鲸,這個(gè)和non-repeatable reads相似烦周,也是同一個(gè)事務(wù)中多次讀不一致的問題尽爆。但是non-repeatable reads的不一致是因?yàn)樗〉臄?shù)據(jù)集被改變了(比如total的數(shù)據(jù)),但是phantom reads所要讀的數(shù)據(jù)的不一致卻不是他所要讀的數(shù)據(jù)集改變读慎,而是他的條件數(shù)據(jù)集改變漱贱。比如Select account.id where account.name="ppgogo*",第一次讀去了6個(gè)符合條件的id,第二次讀取的時(shí)候夭委,由于事務(wù)b把一個(gè)帳號(hào)的名字由"dd"改成"ppgogo1"幅狮,結(jié)果取出來了7個(gè)數(shù)據(jù)。

數(shù)據(jù)庫提供了四種事務(wù)隔離級(jí)別, 不同的隔離級(jí)別采用不同的鎖類開來實(shí)現(xiàn).

在四種隔離級(jí)別中, Serializable的級(jí)別最高, Read Uncommited級(jí)別最低.

大多數(shù)數(shù)據(jù)庫的默認(rèn)隔離級(jí)別為: Read Commited,如Sql Server , Oracle.

少數(shù)數(shù)據(jù)庫默認(rèn)的隔離級(jí)別為Repeatable Read, 如MySQL InnoDB存儲(chǔ)引擎

3闰靴、Transactional注意點(diǎn)

Transactional特性

  • service實(shí)現(xiàn)類標(biāo)簽
    在service實(shí)現(xiàn)類 類頭(一般不建議在接口上)上添加@Transactional彪笼,可以將整個(gè)類納入spring事務(wù)管理,在每個(gè)業(yè)務(wù)方法執(zhí)行時(shí)都會(huì)開啟一個(gè)事務(wù)蚂且,不過這些事務(wù)采用相同的管理方式配猫。
  • 可見度
    @Transactional 注解只能應(yīng)用到 public 可見度的方法上。 如果應(yīng)用在protected杏死、private或者 package可見度的方法上泵肄,也不會(huì)報(bào)錯(cuò),不過事務(wù)設(shè)置不會(huì)起作用淑翼。
  • 回滾
    默認(rèn)情況下腐巢,spring會(huì)對(duì)unchecked異常進(jìn)行事務(wù)回滾;如果是checked異常則不回滾玄括。
    通俗一點(diǎn):你寫代碼出現(xiàn)的空指針等異常冯丙,會(huì)被回滾,文件讀寫遭京,網(wǎng)絡(luò)出問題胃惜,spring就沒法回滾了。

java里面將派生于Error或者RuntimeException(比如空指針哪雕,1/0)的異常稱為unchecked異常船殉,其他繼承自java.lang.Exception得異常統(tǒng)稱為Checked Exception,如IOException斯嚎、TimeoutException

  • 只讀事務(wù)
    只讀標(biāo)志只在事務(wù)啟動(dòng)時(shí)應(yīng)用利虫,否則即使配置也會(huì)被忽略。
    啟動(dòng)事務(wù)會(huì)增加線程開銷堡僻,數(shù)據(jù)庫因共享讀取而鎖定(具體跟數(shù)據(jù)庫類型和事務(wù)隔離級(jí)別有關(guān))糠惫。通常情況下,僅是讀取數(shù)據(jù)時(shí)钉疫,不必設(shè)置只讀事務(wù)而增加額外的系統(tǒng)開銷硼讽。

解決Transactional不回滾

1、檢查方法是否是public的陌选。
2理郑、異常類型是否是unchecked異常

如果想check異常也想回滾怎么辦,注解上面寫明異常類型即可

 @Transactional(rollbackFor=Exception.class)

3咨油、spring是否開啟對(duì)注解的解析

  • @EnableTransactionManagement
  • 還有例如SpringDataJPA 事務(wù)容器聲明:
    transactionManager(JpaTransactionManager) -> entityManagerFactory(EntityManagerFactory) -> dataSource
    4您炉、spring是否掃描到包
    5、數(shù)據(jù)庫引擎是否支持事務(wù)

事務(wù)綁定事件@TransactionalEventListener

1役电、 使用DEMO

@Service
public class TransactionEventTestService {
    @Resource
    private TestMapper mapper;
    @Resource
    private ApplicationEventPublisher publisher;
    @Transactional
    public void addTestModel() {
        TestModel model = new TestModel();
        model.setName("haogrgr");
        mapper.insert(model);
        //如果model沒有繼承ApplicationEvent, 則內(nèi)部會(huì)包裝為PayloadApplicationEvent
        //對(duì)于@TransactionalEventListener, 會(huì)在事務(wù)提交后才執(zhí)行Listener處理邏輯.
        
        //發(fā)布事件, 事務(wù)提交后, 記錄日志, 或發(fā)送消息等操作
        publisher.publishEvent(model);
    }
    //當(dāng)事務(wù)提交后, 才會(huì)真正的執(zhí)行@TransactionalEventListener配置的Listener, 如果Listener拋異常, 方法返回失敗, 但事務(wù)不會(huì)回滾.
}
@Component
public class TransactionEventListener {
    @TransactionalEventListener
    public void handle(PayloadApplicationEvent<TestModel> event) {
        System.out.println(event.getPayload().getName());
        //這里可以記錄日志, 發(fā)送消息等操作.
        //這里拋出異常, 會(huì)導(dǎo)致addTestModel方法異常, 但不會(huì)回滾事務(wù).
        //注意, ApplicationEventPublisher不能使用線程池, 否則不會(huì)執(zhí)行到這里
        //因?yàn)? 包裝類是通過ThreadLocal來判斷當(dāng)前是否有活動(dòng)的事務(wù)信息.
        //TransactionalEventListener.fallbackExecution就是為了決定當(dāng)當(dāng)前線程沒有事務(wù)上下文時(shí),
        //是否還調(diào)用 handle 方法, 默認(rèn)不調(diào)用.
    }
}

2赚爵、TransactionalEventListener詳解

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {

    // 指定當(dāng)前標(biāo)注方法處理事務(wù)的類型
    TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;

    // 用于指定當(dāng)前方法如果沒有事務(wù),是否執(zhí)行相應(yīng)的事務(wù)事件監(jiān)聽器
    boolean fallbackExecution() default false;

    // 與classes屬性一樣法瑟,指定了當(dāng)前事件傳入的參數(shù)類型冀膝,指定了這個(gè)參數(shù)之后就可以在監(jiān)聽方法上
    // 直接什么一個(gè)這個(gè)參數(shù)了
    @AliasFor(annotation = EventListener.class, attribute = "classes")
    Class<?>[] value() default {};

    // 作用于value屬性一樣,用于指定當(dāng)前監(jiān)聽方法的參數(shù)類型
    @AliasFor(annotation = EventListener.class, attribute = "classes")
    Class<?>[] classes() default {};

    // 這個(gè)屬性使用Spring Expression Language對(duì)目標(biāo)類和方法進(jìn)行匹配霎挟,對(duì)于不匹配的方法將會(huì)過濾掉
    String condition() default "";

}

關(guān)于這里的classes屬性需要說明一下窝剖,如果指定了classes屬性,那么當(dāng)前監(jiān)聽方法的參數(shù)類型就可以直接使用所發(fā)布的事件的參數(shù)類型酥夭,如果沒有指定赐纱,那么這里監(jiān)聽的參數(shù)類型可以使用兩種:ApplicationEvent和PayloadApplicationEvent。對(duì)于ApplicationEvent類型的參數(shù)熬北,可以通過其getSource()方法獲取發(fā)布的事件參數(shù)疙描,只不過其返回值是一個(gè)Object類型的,如果想獲取具體的類型還需要進(jìn)行強(qiáng)轉(zhuǎn)讶隐;對(duì)于PayloadApplicationEvent類型起胰,其可以指定一個(gè)泛型參數(shù),該泛型參數(shù)必須與發(fā)布的事件的參數(shù)類型一致巫延,這樣就可以通過其getPayload()方法獲取事務(wù)事件發(fā)布的數(shù)據(jù)了效五。關(guān)于上述屬性中的TransactionPhase,其可以取如下幾個(gè)類型的值:

public enum TransactionPhase {
    // 指定目標(biāo)方法在事務(wù)commit之前執(zhí)行
    BEFORE_COMMIT,

    // 指定目標(biāo)方法在事務(wù)commit之后執(zhí)行
    AFTER_COMMIT,

    // 指定目標(biāo)方法在事務(wù)rollback之后執(zhí)行
    AFTER_ROLLBACK,
    
    // 指定目標(biāo)方法在事務(wù)完成時(shí)執(zhí)行烈评,這里的完成是指無論事務(wù)是成功提交還是事務(wù)回滾了
    AFTER_COMPLETION
}

如何通過程序判斷是否存在事務(wù)火俄?

boolean flag = TransactionSynchronizationManager.isActualTransactionActive();

在同一類中一個(gè)調(diào)用本類中另一個(gè)有事務(wù)的方法,事務(wù)是無效的 解決辦法

1、 將這部分業(yè)務(wù)代碼寫到另一個(gè)service中,然后注入調(diào)用
2讲冠、要調(diào)用代理類才會(huì)被切進(jìn)去

  • ((TestService) SpringContextUtils.getBean("testService")).testTransactional2();

applicationContext 如何獲裙峡汀:
https://blog.csdn.net/u010784959/article/details/78892020

@Autowired
private ApplicationContext applicationContext;
applicationContext.getBean(TestService.class);

3、(推薦)通過ThreadLocal暴露代理對(duì)象

  • 第一步:開啟cglib代理竿开。spring.aop.proxy-target-class:true
  • 第二步:@EnableAspectJAutoProxy(exposeProxy = true)
  • 第三步:方法一中調(diào)用方法兒如:((TestService)AopContext.currentProxy()).testTransactional2();

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谱仪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子否彩,更是在濱河造成了極大的恐慌疯攒,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件列荔,死亡現(xiàn)場(chǎng)離奇詭異敬尺,居然都是意外死亡枚尼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門砂吞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來署恍,“玉大人,你說我怎么就攤上這事蜻直《⒅剩” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵概而,是天一觀的道長呼巷。 經(jīng)常有香客問我,道長赎瑰,這世上最難降的妖魔是什么王悍? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮乡范,結(jié)果婚禮上配名,老公的妹妹穿的比我還像新娘。我一直安慰自己晋辆,他們只是感情好渠脉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瓶佳,像睡著了一般芋膘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上霸饲,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天为朋,我揣著相機(jī)與錄音,去河邊找鬼厚脉。 笑死习寸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的傻工。 我是一名探鬼主播霞溪,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼中捆!你這毒婦竟也來了鸯匹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤泄伪,失蹤者是張志新(化名)和其女友劉穎殴蓬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蟋滴,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡染厅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年痘绎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肖粮。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡简逮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尿赚,到底是詐尸還是另有隱情,我是刑警寧澤蕉堰,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布凌净,位于F島的核電站,受9級(jí)特大地震影響屋讶,放射性物質(zhì)發(fā)生泄漏冰寻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一皿渗、第九天 我趴在偏房一處隱蔽的房頂上張望斩芭。 院中可真熱鬧,春花似錦乐疆、人聲如沸划乖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琴庵。三九已至拂盯,卻和暖如春霉颠,著一層夾襖步出監(jiān)牢的瞬間迂烁,已是汗流浹背敷搪。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工紊选, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乞巧,地道東北人走净。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓银择,卻偏偏與公主長得像诉字,于是被迫代替她去往敵國和親懦尝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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