5-事務、數(shù)據(jù)庫事務攘须、事務隔離級別漆撞、鎖的簡單總結

轉載自:http://www.reibang.com/p/818d2b41c743


一、數(shù)據(jù)庫事務

1阻课、事務是作為單個邏輯工作單元執(zhí)行的一系列操作叫挟。可以是一條SQL語句也可以是多條SQL語句限煞。

2抹恳、事務具有四個特性

原子性(Atomicity):事務中的全部操作在數(shù)據(jù)庫中是不可分割的,要么全部完成署驻,要么均不執(zhí)行奋献。

一致性(Consistency):幾個并行執(zhí)行的事務健霹,其執(zhí)行結果必須與按某一順序串行執(zhí)行的結果相一致。

隔離性(Isolation):事務的執(zhí)行不受其他事務的干擾瓶蚂,事務執(zhí)行的中間結果對其他事務必須是透明的糖埋。

持久性(Durability):對于任意已提交事務,系統(tǒng)必須保證該事務對數(shù)據(jù)庫的改變不被丟失窃这,即使數(shù)據(jù)庫出現(xiàn)故障瞳别。

3、啟動事務:使用 API 函數(shù)和 Transact-SQL 語句杭攻,可以按顯式祟敛、自動提交或隱式的方式來啟動事務。

4兆解、結束事務:您可以使用 COMMIT(成功) 或 ROLLBACK(失敼萏) 語句,或者通過 API 函數(shù)來結束事務锅睛。

5埠巨、創(chuàng)建事務的原則

盡可能使事務保持簡短很重要,當事務啟動后现拒,數(shù)據(jù)庫管理系統(tǒng) (DBMS) 必須在事務結束之前保留很多資源辣垒、以保證事務的正確安全執(zhí)行。

特別是在大量并發(fā)的系統(tǒng)中具练, 保持事務簡短以減少并發(fā) 資源鎖定爭奪乍构,將顯得更為重要甜无。

a扛点、事務處理,禁止與用戶交互岂丘,在事務開始前完成用戶輸入陵究。

b、在瀏覽數(shù)據(jù)時奥帘,盡量不要打開事務

c铜邮、盡可能使事務保持簡短。

d寨蹋、考慮為只讀查詢使用快照隔離松蒜,以減少阻塞。

e已旧、靈活地使用更低的事務隔離級別秸苗。

f、靈活地使用更低的游標并發(fā)選項运褪,例如開放式并發(fā)選項惊楼。

g玖瘸、在事務中盡量使訪問的數(shù)據(jù)量最小。

二檀咙、事務的隔離級別

1雅倒、事務常見的四種隔離級別

盡管數(shù)據(jù)庫為用戶提供了鎖的DML操作方式,但直接使用鎖管理是非常麻煩的弧可,因此數(shù)據(jù)庫為用戶提供了自動鎖機制蔑匣。只要用戶指定會話的事務隔離級別,數(shù)據(jù)庫就會分析事務中的SQL語句棕诵,然后自動為事務操作的數(shù)據(jù)資源添加上適合的鎖殖演。此外數(shù)據(jù)庫還會維護這些鎖,當一個資源上的鎖數(shù)目太多時年鸳,自動進行鎖升級以提高系統(tǒng)的運行性能趴久,而這一過程對用戶來說完全是透明的。

ANSI/ISO SQL 92標準定義了4個等級的事務隔離級別搔确,在相同數(shù)據(jù)環(huán)境下彼棍,使用相同的輸入,執(zhí)行相同的工作膳算,根據(jù)不同的隔離級別座硕,可以導致不同的結果。不同事務隔離級別能夠解決的數(shù)據(jù)并發(fā)問題的能力是不同的涕蜂,如下表:

事務的隔離級別和數(shù)據(jù)庫并發(fā)性是對立的华匾,兩者此增彼長。一般來說机隙,使用READ UNCOMMITED隔離級別的數(shù)據(jù)庫擁有最高的并發(fā)性和吞吐量蜘拉,而使用SERIALIZABLE隔離級別的數(shù)據(jù)庫并發(fā)性最低。

SQL 92定義READ UNCOMMITED主要是為了提供非阻塞讀的能力有鹿,Oracle雖然也支持READ UNCOMMITED旭旭,但它不支持臟讀,因為Oracle使用多版本機制徹底解決了在非阻塞讀時讀到臟數(shù)據(jù)的問題并保證讀的一致性葱跋,所以持寄,Oracle的READ COMMITTED隔離級別就已經滿足了SQL 92標準的REPEATABLE READ隔離級別。?SQL 92推薦使用REPEATABLE READ以保證數(shù)據(jù)的讀一致性娱俺,不過用戶可以根據(jù)應用的需要選擇適合的隔離等級稍味。

問題分析:

a、更新丟失:兩個事務都同時更新一行數(shù)據(jù)荠卷,一個事務對數(shù)據(jù)的更新把另一個事務對數(shù)據(jù)的更新覆蓋了模庐。這是因為系統(tǒng)沒有執(zhí)行任何的鎖操作,并發(fā)事務沒有被隔離開來僵朗。

第一類更新丟失:A事務撤銷時赖欣,把已經提交的B事務的更新數(shù)據(jù)覆蓋了屑彻。這種錯誤可能造成很嚴重的問題,通常數(shù)據(jù)庫的實現(xiàn)是不允許發(fā)生這種情況顶吮。

第二類更新丟失:A事務覆蓋B事務已經提交的數(shù)據(jù)社牲,造成B事務所做操作丟失。

b悴了、臟讀(Dirty Read):一個事務讀取到了另一個事務未提交的數(shù)據(jù)操作結果搏恤。這是相當危險的,因為很可能所有的操作都被回滾湃交。

c熟空、不可重復讀(虛讀)(NonRepeatable Read):一個事務對同一行數(shù)據(jù)重復讀取兩次,但是卻得到了不同的結果搞莺。例如事務T1讀取某一數(shù)據(jù)后息罗,事務T2對其做了修改,當事務T1再次讀該數(shù)據(jù)時得到與前一次不同的值才沧。

d迈喉、幻讀(Phantom Read):事務在操作過程中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現(xiàn)的數(shù)據(jù)或者缺少了第一次查詢中出現(xiàn)的數(shù)據(jù)温圆,這是因為在兩次查詢過程中有另外一個事務插入數(shù)據(jù)造成的挨摸。

隔離級別分析:

a、讀未提交(Read Uncommitted):允許臟讀取岁歉,但不允許更新丟失得运。這種事務隔離控制可以通過“排他寫鎖”實現(xiàn)。

b锅移、讀提交(Read Committed):允許不可重復讀取熔掺,但不允許臟讀取。這種事務隔離控制可以通過“瞬間共享讀鎖”和“排他寫鎖”實現(xiàn)帆啃。

c瞬女、可重復讀(Repeatable Read):禁止不可重復讀取和臟讀取,但是有時可能出現(xiàn)幻影數(shù)據(jù)努潘。這種事務隔離控制可以通過“共享讀鎖”和“排他寫鎖”實現(xiàn)。

d坤学、可序列化(Serializable):提供嚴格的事務隔離疯坤。它要求事務序列化執(zhí)行,事務只能一個接著一個地執(zhí)行深浮,但不能并發(fā)執(zhí)行压怠。如果僅僅通過“行級鎖”是無法實現(xiàn)事務序列化的,必須通過其他機制保證新插入的數(shù)據(jù)不會被剛執(zhí)行查詢操作的事務訪問到飞苇。

2菌瘫、數(shù)據(jù)庫中蜗顽,通常默認隔離級別是“讀已提交”,在默認的事務隔離級別下:insert雨让,update雇盖,delete用的是排他鎖, 會等待事務完成。通常情況下可以把隔離級別設為Read Committed栖忠,它能避免臟讀崔挖,而且有較好的并發(fā)性能。盡管它會導致虛讀庵寞、幻讀等問題狸相,在可能出現(xiàn)這類問題的個別場合可以由應用程序釆用悲觀鎖或樂觀鎖來控制。

3捐川、SQL語句執(zhí)行之前脓鹃,一般可以通過自定義設置事務隔離級別,JDBC一般也支持修改會話級的事務隔離級別設置古沥。

4将谊、另外要提一點:SQL標準對事務隔離級別的規(guī)定,是按該級別不可能發(fā)生什么問題來確定的渐白;所以尊浓,不同的數(shù)據(jù)庫對事務隔離的級別實現(xiàn)方式不一樣,比如纯衍,鎖的類型栋齿、鎖的作用范圍與鎖的有效時間。

5襟诸、事務隔離級別的實現(xiàn)依據(jù)

a瓦堵、是否申請鎖和鎖類型

b、占用鎖的時間

c歌亲、鎖的粒度

例如:共享鎖的鎖定時間與事務的隔離級別有關菇用,如果隔離級別為Read

Committed的默認級別,只在讀取(select)的期間保持鎖定陷揪,即在查詢出數(shù)據(jù)以后就釋放了鎖惋鸥;如果隔離級別為更高的Serializable直到事務結束才釋放鎖。另說明悍缠,如果select語句中指定了HoldLock提示卦绣,則也要等到事務結束才釋放鎖。

三飞蚓、鎖

1滤港、事務使用鎖,防止其他用戶訪問一個還未完成的事務中的數(shù)據(jù)趴拧。對于多用戶系統(tǒng)來說溅漾,鎖機制是必須的山叮。有多種類型的鎖,允許事務鎖定不同的資源添履。鎖就是保護指定的資源屁倔,不被其他事務操作。鎖定比較小的對象缝龄,例如鎖定行汰现,雖然可以提高并發(fā)性,但是卻有較高的開支叔壤,因為如果鎖定許多行瞎饲,那么需要占有更多的鎖。鎖定比較大的對象炼绘,例如鎖定表嗅战,會大大降低并發(fā)性,因為鎖定整個表就限制了其他事務訪問該表的其他部分俺亮,但是成本開支比較低驮捍,因為只需維護比較少的鎖。

2脚曾、鎖的特點:

a东且、鎖是保證并發(fā)控制的手段

b、鎖的類型本讥,主要包括共享鎖和排它鎖珊泳;共享鎖允許其他事務繼續(xù)使用鎖定的資源,排它鎖只允許一個事務訪問數(shù)據(jù)

c拷沸、鎖的粒度色查,可以鎖定的資源包括行、頁撞芍、簇秧了、表和數(shù)據(jù)庫

d、鎖的時間序无,鎖的時間應該包括兩種:一種是sql執(zhí)行完就釋放鎖验毡,另一種是事務結束后釋放鎖。

3愉镰、數(shù)據(jù)庫鎖機制

數(shù)據(jù)庫通過鎖的機制解決并發(fā)訪問的問題米罚,雖然不同的數(shù)據(jù)庫在實現(xiàn)細節(jié)上存在差別,但原理基本上是一樣的丈探。

按鎖定的對象的不同,一般可以分為表鎖定行鎖定拔莱,前者對整個表進行鎖定碗降,而后者對表中特定行進行鎖定隘竭。從并發(fā)事務鎖定的關系上看,可以分為共享鎖定獨占鎖定讼渊。共享鎖定會防止獨占鎖定动看,但允許其他的共享鎖定。而獨占鎖定既防止其他的獨占鎖定爪幻,也防止其他的共享鎖定菱皆。

為了更改數(shù)據(jù),數(shù)據(jù)庫必須在進行更改的行上施加行獨占鎖定挨稿,INSERT仇轻、UPDATE、DELETE和SELECT FOR UPDATE語句都會隱式采用必要的行鎖定奶甘。

4篷店、InnoDB引擎的鎖機制

共享鎖(S):允許一個事務去讀一行,阻止其他事務獲得相同數(shù)據(jù)集的排他鎖臭家。

排他鎖(X):允許獲得排他鎖的事務更新數(shù)據(jù)疲陕,阻止其他事務取得相同數(shù)據(jù)集的共享讀鎖和排他寫鎖。

意向共享鎖(IS):事務打算給數(shù)據(jù)行加行共享鎖钉赁,事務在給一個數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖蹄殃。

意向排他鎖(IX):事務打算給數(shù)據(jù)行加行排他鎖,事務在給一個數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖你踩。

說明:

1)共享鎖和排他鎖都是行鎖诅岩,意向鎖都是表鎖,應用中我們只會使用到共享鎖和排他鎖姓蜂,意向鎖是mysql內部使用的按厘,不需要用戶干預。

2)對于UPDATE钱慢、DELETE和INSERT語句逮京,InnoDB會自動給涉及數(shù)據(jù)集加排他鎖;對于普通SELECT語句束莫,InnoDB不會加任何鎖懒棉,事務可以通過以下語句顯示給記錄集加共享鎖或排他鎖。

共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE

3)InnoDB行鎖是通過給索引上的索引項加鎖來實現(xiàn)的览绿,因此InnoDB這種行鎖實現(xiàn)特點意味著:只有通過索引條件檢索數(shù)據(jù)策严,InnoDB才使用行級鎖,否則饿敲,InnoDB將使用表鎖妻导!

5、程序使用鎖(并發(fā)控制類型分為兩大類:樂觀并發(fā)控制和悲觀并發(fā)控制)

悲觀鎖( Pessimistic Locking )

悲觀鎖,正如其名倔韭,它指的是對數(shù)據(jù)被外界(包括本系統(tǒng)當前的其他事務术浪,以及來自外部系統(tǒng)的事務處理)修改持保守態(tài)度,因此寿酌,在整個數(shù)據(jù)處理過程中胰苏,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實現(xiàn)醇疼,往往依靠數(shù)據(jù)庫提供的鎖機制(也只有數(shù)據(jù)庫層提供的鎖機制才能真正保證數(shù)據(jù)訪問的排他性硕并,否則,即使在本系統(tǒng)中實現(xiàn)了加鎖機制秧荆,也無法保證外部系統(tǒng)不會修改數(shù)據(jù))倔毙。

一個典型的依賴數(shù)據(jù)庫的悲觀鎖調用:

select * from account where name=”Erica” for update

這條 sql 語句鎖定了 account 表中所有符合檢索條件(name=”Erica”)的記錄。本次事務提交之前(事務提交時會釋放事務過程中的鎖)辰如,外界無法修改這些記錄普监。

Hibernate 的悲觀鎖,也是基于數(shù)據(jù)庫的鎖機制實現(xiàn)琉兜。

下面的代碼實現(xiàn)了對查詢記錄的加鎖:

String hqlStr ="from TUser as user where user.name='Erica'";

Query query = session.createQuery(hqlStr);

query.setLockMode("user", LockMode.UPGRADE); // 加鎖

List userList = query.list();// 執(zhí)行查詢凯正,獲取數(shù)據(jù)

query.setLockMode 對查詢語句中,特定別名所對應的記錄進行加鎖(我們?yōu)門User 類指定了一個別名 “user” )豌蟋,這里也就是對返回的所有 user 記錄進行加鎖廊散。

Hibernate 通過使用數(shù)據(jù)庫的 for update 子句實現(xiàn)了悲觀鎖機制。

Hibernate 的加鎖模式有:

LockMode.NONE :無鎖機制梧疲。

LockMode.WRITE :Hibernate 在 Insert 和 Update 記錄的時候會自動獲取允睹。

LockMode.READ :Hibernate 在讀取記錄的時候會自動獲取炕横。

以上這三種鎖機制一般由 Hibernate 內部使用实苞,如 Hibernate 為了保證 Update過程中對象不會被外界修改,會在 save 方法實現(xiàn)中自動為目標對象加上 WRITE 鎖鹿驼。

LockMode.UPGRADE :利用數(shù)據(jù)庫的 for update 子句加鎖该互。

LockMode. UPGRADE_NOWAIT :Oracle 的特定實現(xiàn)米者,利用 Oracle 的 for update nowait 子句實現(xiàn)加鎖。

上面這兩種鎖機制是我們在應用層較為常用的宇智,加鎖一般通過以下方法實現(xiàn):

Criteria.setLockMode

Query.setLockMode

Session.lock

注意蔓搞,只有在查詢開始之前(也就是 Hiberate 生成 SQL 之前)設定加鎖,才會真正通過數(shù)據(jù)庫的鎖機制進行加鎖處理随橘,否則喂分,數(shù)據(jù)已經通過不包含 for update 子句的 Select SQL 加載進來,所謂數(shù)據(jù)庫加鎖也就無從談起机蔗。

樂觀鎖( Optimistic Locking )

相對悲觀鎖而言蒲祈,樂觀鎖機制采取了更加寬松的加鎖機制甘萧。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫的鎖機制實現(xiàn),以保證操作最大程度的獨占性讳嘱。但隨之而來的就是數(shù)據(jù)庫性能的大量開銷幔嗦,特別是對長事務而言酿愧,這樣的開銷往往無法承受沥潭。

如一個金融系統(tǒng),當某個操作員讀取用戶的數(shù)據(jù)嬉挡,并在讀出的用戶數(shù)據(jù)的基礎上進行修改時如更改用戶帳戶余額钝鸽,如果采用悲觀鎖機制,也就意味著整個操作過程中(從操作員讀出數(shù)庞钢、開始修改直至提交修改結果的全過程拔恰,甚至還包括操作員中途去煮咖啡的時間),數(shù)據(jù)庫記錄始終處于加鎖狀態(tài)基括,可以想見颜懊,如果面對幾百上千個并發(fā),這樣的情況將導致怎樣的后果风皿。樂觀鎖機制在一定程度上解決了這個問題河爹。

樂觀鎖,大多是基于數(shù)據(jù)版本( Version

)記錄機制實現(xiàn)桐款。何謂數(shù)據(jù)版本咸这?即為數(shù)據(jù)增加一個版本標識,在基于數(shù)據(jù)庫表的版本解決方案中魔眨,一般是通過為數(shù)據(jù)庫表增加一個 “version”

字段來實現(xiàn)媳维。

讀取出數(shù)據(jù)時,將此版本號一同讀出遏暴,之后更新時侄刽,對此版本號加一。此時朋凉,將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫表對應記錄的當前版本信息進行比對州丹,如果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫表當前版本號,則予以更新侥啤,否則認為是過期數(shù)據(jù)当叭。

對于上面修改用戶帳戶信息的例子而言,假設數(shù)據(jù)庫中帳戶信息表中有一個version 字段盖灸,當前值為 1 蚁鳖;而當前帳戶余額字段(balance)為 $100 。

a> 操作員 A 此時將其讀出(version=1)赁炎,并從其帳戶余額中扣除 $50($100-$50)醉箕。

b> 在操作員 A 操作的過程中钾腺,操作員 B 也讀入此用戶信息(version=1),并從其帳戶余額中扣除 $20 ($100-$20)讥裤。

c> 操作員 A 完成了修改工作放棒,將數(shù)據(jù)版本號加一(version=2),連同帳戶扣除后余額(balance=$50)己英,提交至數(shù)據(jù)庫更新间螟,此時由于提交數(shù)據(jù)版本大于數(shù)據(jù)庫記錄當前版本,數(shù)據(jù)被更新损肛,數(shù)據(jù)庫記錄 version 更新為 2 厢破。

d> 操作員 B 完成了操作,也將版本號加一(version=2)試圖向數(shù)據(jù)庫提交數(shù)據(jù)(balance=$80)治拿,但此時比對數(shù)據(jù)庫記錄版本時發(fā)現(xiàn)摩泪,操作員 B 提交的數(shù)據(jù)版本號為 2 ,數(shù)據(jù)庫記錄當前版本也為 2 劫谅,不滿足“ 提交版本必須大于記錄當前版本才能執(zhí)行更新“ 的樂觀鎖策略见坑,因此,操作員 B 的提交被駁回捏检。這樣荞驴,就避免了操作員 B 用基于 version=1 的舊數(shù)據(jù)修改的結果覆蓋操作員 A 的操作結果的可能。

從上面的例子可以看出未檩,樂觀鎖機制避免了長事務中的數(shù)據(jù)庫加鎖開銷(操作員 A 和操作員 B 操作過程中戴尸,都沒有對數(shù)據(jù)庫數(shù)據(jù)加鎖),大大提升了大并發(fā)量下的系統(tǒng)整體性能表現(xiàn)冤狡。需要注意的是孙蒙,樂觀鎖機制往往基于系統(tǒng)中的數(shù)據(jù)存儲邏輯,因此也具備一定的局限性悲雳,如在上例中挎峦,由于樂觀鎖機制是在我們的系統(tǒng)中實現(xiàn),來自外部系統(tǒng)的用戶余額更新操作不受我們系統(tǒng)的控制合瓢,因此可能會造成臟數(shù)據(jù)被更新到數(shù)據(jù)庫中坦胶。在系統(tǒng)設計階段,我們應該充分考慮到這些情況出現(xiàn)的可能性晴楔,并進行相應調整(比如可以將樂觀鎖策略放在數(shù)據(jù)庫存儲過程中實現(xiàn)顿苇,對外只開放基于此存儲過程的數(shù)據(jù)更新途徑,而不是將數(shù)據(jù)庫表直接對外公開)税弃。

Hibernate 在其數(shù)據(jù)訪問引擎中內置了樂觀鎖實現(xiàn)纪岁。如果不用考慮外部系統(tǒng)對數(shù)據(jù)庫的更新操作,利用 Hibernate 提供的透明化樂觀鎖實現(xiàn)则果,將大大提升我們的生產力幔翰。

Hibernate 中可以通過 class 描述符的 optimistic-lock 屬性結合 version描述符指定漩氨。

現(xiàn)在,我們?yōu)橹笆纠械?TUser 加上樂觀鎖機制遗增。

1 . 首先為 TUser 的 class 描述符添加 optimistic-lock 屬性:

dynamic-insert="true" optimistic-lock="version">

……

optimistic-lock 屬性有如下可選取值:

none:無樂觀鎖

version:通過版本機制實現(xiàn)樂觀鎖

dirty:通過檢查發(fā)生變動過的屬性實現(xiàn)樂觀鎖

all:通過檢查所有屬性實現(xiàn)樂觀鎖

其中通過 version 實現(xiàn)的樂觀鎖機制是 Hibernate 官方推薦的樂觀鎖實現(xiàn)叫惊,同時也是 Hibernate 中,目前唯一在數(shù)據(jù)對象脫離 Session 發(fā)生修改的情況下依然有效的鎖機制做修。因此霍狰,一般情況下,我們都選擇 version 方式作為 Hibernate 樂觀鎖實現(xiàn)機制缓待。

2 . 添加一個 Version 屬性描述符

optimistic-lock="version">

……

注意 version 節(jié)點必須出現(xiàn)在 ID 節(jié)點之后蚓耽。這里我們聲明了一個 version 屬性,用于存放用戶的版本信息旋炒,保存在 TUser 表的version 字段中。

在代碼中執(zhí) tx.commit() 時可能拋出 StaleObjectStateException 異常签杈,指出版本檢查失敗瘫镇,說明當前事務正在試圖提交一個過期數(shù)據(jù)。通過捕捉這個異常答姥,我們就可以在樂觀鎖校驗失敗時進行相應處理铣除。

五、Java中的三種事務

差異:

1鹦付、JDBC事務控制的局限性在一個數(shù)據(jù)庫連接內尚粘,但是其使用簡單。

2敲长、JTA事務的功能強大郎嫁,事務可以跨越多個數(shù)據(jù)庫或多個DAO,使用也比較復雜祈噪;應用程序調用UserTransaction.begin()泽铛、 UserTransaction.commit() 和 serTransaction.rollback() 處理事務邊界。

3辑鲤、容器事務盔腔,主要指的是J2EE應用服務器提供的事務管理,局限于EJB應用使用月褥。

小禮物走一走弛随,來簡書關注我

贊賞支持

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市宁赤,隨后出現(xiàn)的幾起案子舀透,更是在濱河造成了極大的恐慌,老刑警劉巖礁击,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盐杂,死亡現(xiàn)場離奇詭異逗载,居然都是意外死亡,警方通過查閱死者的電腦和手機链烈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門厉斟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人强衡,你說我怎么就攤上這事擦秽。” “怎么了漩勤?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵感挥,是天一觀的道長。 經常有香客問我越败,道長触幼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任究飞,我火速辦了婚禮置谦,結果婚禮上,老公的妹妹穿的比我還像新娘亿傅。我一直安慰自己媒峡,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布葵擎。 她就那樣靜靜地躺著谅阿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酬滤。 梳的紋絲不亂的頭發(fā)上签餐,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音敏晤,去河邊找鬼贱田。 笑死,一個胖子當著我的面吹牛嘴脾,可吹牛的內容都是我干的男摧。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼译打,長吁一口氣:“原來是場噩夢啊……” “哼耗拓!你這毒婦竟也來了?” 一聲冷哼從身側響起奏司,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤乔询,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后韵洋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竿刁,經...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡黄锤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了食拜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸵熟。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖负甸,靈堂內的尸體忽然破棺而出流强,到底是詐尸還是另有隱情,我是刑警寧澤呻待,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布打月,位于F島的核電站,受9級特大地震影響蚕捉,放射性物質發(fā)生泄漏奏篙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一鱼冀、第九天 我趴在偏房一處隱蔽的房頂上張望报破。 院中可真熱鬧,春花似錦千绪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至炸茧,卻和暖如春瑞妇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背梭冠。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工辕狰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人控漠。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓蔓倍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盐捷。 傳聞我的和親對象是個殘疾皇子偶翅,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內容