JDBC_事務(wù)管理

一谁榜、什么是事務(wù)

邏輯上的一組操作, 侈沪,要不全部失敗,要不全部成功。

對(duì)數(shù)據(jù)庫(kù)的操作會(huì)先在一張臨時(shí)表上進(jìn)行绣张,一旦發(fā)生錯(cuò)誤纤掸,就回滾撤銷所有操作恰响。全部成功才存盤修改數(shù)據(jù)庫(kù)數(shù)據(jù)税肪。

MySql的事務(wù)管理

1. 啟動(dòng)事務(wù)(對(duì)數(shù)據(jù)的操作在臨時(shí)表中進(jìn)行)
    startTransaction

2. 提交,存盤
    commit

3. 回滾,撤銷
    rollBack
  • 在事務(wù)管理中執(zhí)行sql,使用數(shù)據(jù)庫(kù)內(nèi)臨時(shí)表保存负乡,在沒有進(jìn)行事務(wù)提交或者回滾之前牛郑,其它用戶無(wú)法看到事務(wù)操作的結(jié)果
  • SQL語(yǔ)言中只有DML才能被事務(wù)管理(insert/update/delete)

JDBC的事務(wù)

1. 啟動(dòng)事務(wù)管理
    //首先獲取連接。(以C3P0為基礎(chǔ)準(zhǔn)備一個(gè)JDBCUtils工具類,提供獲取連接池和連接的方法)
    Connection connection = JDBCUtils.getConnection();
    //啟動(dòng)事務(wù)
    connection.setAutoCommit(false);

2. 提交,存盤
    connection.commit();

3. 回滾敬鬓,撤銷
    connection.rollBack();

DBUtils的事務(wù)管理

1. 啟動(dòng)事務(wù)
    //創(chuàng)建QuueryRunner對(duì)象,使用它的無(wú)參構(gòu)造方式,自己給連接淹朋。從而可以通過(guò)連接控制事務(wù)
    QueryRunner runner = new QueryRunner();
    Connection connection = JDBCUtils.getConnection();
    connection.setAutoCommit(false);

2. 提交并釋放資源,異常由框架處理(其實(shí)沒處理)
    //connection.commitAndCloseQuietly();

3. 回滾,撤銷并釋放資源,異常由框架處理(其實(shí)沒處理)
    //connection.rollbackAndCloseQuietly();

事務(wù)回滾點(diǎn) SavePoint(類似與游戲中的存檔)

當(dāng)事務(wù)特別復(fù)雜笙各,有些情況不會(huì)回滾到事務(wù)的最開始狀態(tài),需要將事務(wù)回滾到指定位置

* 核心API
    * connection.setSavepoint();// 設(shè)置回滾點(diǎn)
    * connection.rollback(savepoint);//事務(wù)回滾到指定回滾點(diǎn)
  • 示例代碼
    • 往數(shù)據(jù)庫(kù)中添加數(shù)據(jù)础芍,每1000條保存一次杈抢。

    Connection connection = null;
    PreparedStatement prepareStatement = null;
    Savepoint savepoint = null;
    try {
        connection = JDBCUtils.getConnection();
        // 開啟事務(wù)
        connection.setAutoCommit(false);
        // 設(shè)置初始回滾點(diǎn)
        savepoint = connection.setSavepoint();
        String sql = "insert into person values (?,?)";
        prepareStatement = connection.prepareStatement(sql);
        for (int i = 1; i <= 5000; i++) {
            prepareStatement.setInt(1, i);
            prepareStatement.setString(2, "name" + i);
            prepareStatement.addBatch();
            // 模擬錯(cuò)誤
            if (i == 3201) {
                int x = 11 / 0;
            }
            // 每隔200條數(shù)據(jù)執(zhí)行一次批處理
            if (i % 200 == 0) {
                prepareStatement.executeBatch();
                prepareStatement.clearBatch();
            }
            if (i % 1000 == 0) {
                // 每一千條數(shù)據(jù),創(chuàng)建一個(gè)回滾點(diǎn)
                savepoint = connection.setSavepoint();
            }
        }
        prepareStatement.executeBatch();
        prepareStatement.clearBatch();
        // 沒有異常,提交事務(wù)
        connection.commit();
    } catch (Exception e) {
        try {
            // 發(fā)生異常,事務(wù)回滾到指定回滾點(diǎn)
            connection.rollback(savepoint);
            // 提交事務(wù)
            connection.commit();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
    } finally {
        JDBCUtils.release(connection, prepareStatement);
    }

二、事務(wù)案例:簡(jiǎn)易轉(zhuǎn)賬案例

1仑性、分析

img01.png

2惶楼、搭建環(huán)境

1. 數(shù)據(jù)庫(kù)及用戶表單的創(chuàng)建。

    CREATE DATABASE day20;
    USE day20;
    CREATE TABLE USER(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(40),
    money DOUBLE
    );
    INSERT INTO USER VALUES(NULL,'tom',2000);
    INSERT INTO USER VALUES(NULL,'jerry',2000);

2. 數(shù)據(jù)庫(kù)驅(qū)動(dòng),c3p0的jar包,c3p0.xml配置文件诊杆,dbutils的jar包,

3. 轉(zhuǎn)賬頁(yè)面
    <form action="${pageContext.request.contextPath}/transfer" method="post">
        轉(zhuǎn)賬人:<input type="text" name="sender" /><br/>
        被轉(zhuǎn)賬人:<input type="text" name="receiver" /><br/>
        轉(zhuǎn)賬金額:<input type="text" name="acount" /><br/>
        <input type="submit" value="轉(zhuǎn)賬">    <br/>
    </form>

3歼捐、分包實(shí)現(xiàn)

3.1、創(chuàng)建web層TransactServlet

Servlet要做的三件事:

  1. 獲取表單提交的參數(shù)
  2. 調(diào)用業(yè)務(wù)邏輯
  3. 分發(fā)轉(zhuǎn)向

    public class TransferServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            // 設(shè)置編碼集
            response.setContentType("text/html;charset=UTF-8");
    
            try {
                // 獲取參數(shù)
                String sender = request.getParameter("sender");
                String receiver = request.getParameter("receiver");
                String amount = request.getParameter("amount");
                
                // 調(diào)用業(yè)務(wù)層對(duì)象,執(zhí)行轉(zhuǎn)賬
                TransferService service = new TransferService();
                service.transfer(sender, receiver, amount);
                // 寫出響應(yīng)
                response.getWriter().write("轉(zhuǎn)賬成功");
            } catch (Exception e) {
                // 寫出響應(yīng)
                response.getWriter().write("轉(zhuǎn)賬失敗:" + e.getMessage());
            }
    
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
}

3.2晨汹、創(chuàng)建service層TransferService

與數(shù)據(jù)庫(kù)交互的操作交到dao層完成豹储,service層只處理業(yè)務(wù)邏輯


    public class TransferService {
    
        public void transfer(String sender, String receiver, String amount) throws Exception {
            Connection connection = null;
    
            try {
                // 與數(shù)據(jù)庫(kù)交互的事情交給dao層去操作 ,創(chuàng)建dao對(duì)象
                TransferDao dao = new TransferDao();
    
                // 開啟事務(wù)。要想控制事務(wù)dao層的connection連接對(duì)象和這里的連接對(duì)象應(yīng)該一致.因此將這個(gè)connection對(duì)象作為參數(shù)傳遞下去淘这。
                //connection = JDBCUtils.getConnection();
                //connection.setAutoCommit(false);
                //為了不打破分層結(jié)構(gòu),不應(yīng)該將連接Connection的操作放在Service層.因此抽取出來(lái)
                JDBCUtils.startTransaction();
    
                // 改變的行數(shù)
                int outDao = dao.outDao(sender, amount);
                
                //一旦數(shù)據(jù)庫(kù)操作失敗,影響行數(shù)即為0剥扣,拋出異常帶上對(duì)應(yīng)的信息。
                if(outDao != 1) {
                    throw new RuntimeException("轉(zhuǎn)出失敗");
                }
                
                int inDao = dao.inDao(receiver, amount);
                
                if(inDao != 1) {
                    throw new RuntimeException("轉(zhuǎn)入失敗");
                }
    
                // 沒有異常,提交事務(wù)
                JDBCUtils.commitAndRelease();

            //這里是用try-catch是為了保證有異常與無(wú)異常時(shí)的兩種處理方式
            //這里抓住了上面拋出的轉(zhuǎn)賬信息的異常但是為了告訴Servlet這里發(fā)生了異常铝穷,將該異常繼續(xù)向上拋
            } catch (Exception e) { 

                // 發(fā)生異常,回滾撤銷操作
                JDBCUtils.rollbackAndRelease();
                throw e;
            }
    
        }
    }

3.3钠怯、創(chuàng)建utils工具類JDBCUtils

提供與數(shù)據(jù)庫(kù)操作相關(guān)的工具:獲取連接池與獲取連接的方法

因?yàn)镈BUtils框架的QueryRunner對(duì)象會(huì)自行釋放資源,因此不提供釋放Connection等資源的方法。

private static DataSource dataSource = new ComboPooledDataSource();

    // 獲取連接池對(duì)象
    public static DataSource getDataSource() {
        return dataSource;
    }

    // 提供連接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

3.4曙聂、創(chuàng)建dao層TransferDao

進(jìn)行操作數(shù)據(jù)庫(kù)的動(dòng)作晦炊。


    public class TransferDao {
    
        public int outDao(String sender, String amount) throws SQLException {
            //對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)進(jìn)行更改
            //1.創(chuàng)建QueryRunner對(duì)象
            QueryRunner runner = new QueryRunner();
            Connection connection = JDBCUtils.getConnectionTL();
            //2.執(zhí)行sql語(yǔ)句
            String sql = "update user set money=money-? where name=?";

            //為了告知service層sql語(yǔ)句是否執(zhí)行成功,返回被影響的行數(shù)
            int i = runner.update(connection, sql, amount,sender);
            return i;
        }
    
        public int inDao(String receiver, String amount) throws SQLException {
            //對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)進(jìn)行更改
            //1.創(chuàng)建QueryRunner對(duì)象
            QueryRunner runner = new QueryRunner(JDBCUtils.getDataSource());
            Connection connection = JDBCUtils.getConnectionTL();
            //2.執(zhí)行sql語(yǔ)句
            String sql = "update user set money=money+? where name=?";
            int i = runner.update(connection, sql, amount,receiver);
            return i;
        }
    }

3.5、優(yōu)化代碼宁脊,完善utils工具類

  1. 因?yàn)榈谝话嬷衧ervice層執(zhí)行了屬于dao層與數(shù)據(jù)庫(kù)交互的操作断国,這打破了三層結(jié)構(gòu),為了避免這種情況朦佩,應(yīng)當(dāng)考慮將與數(shù)據(jù)庫(kù)交互的相關(guān)操作抽取出來(lái)并思,于是我將控制事務(wù)的代碼抽取到工具類中庐氮。提供開啟事務(wù)语稠,提交事務(wù)和回滾事務(wù)的方法。

  2. 但是為了控制事務(wù)弄砍,service層和dao層的connection應(yīng)當(dāng)是同一個(gè)connection仙畦,因此使用了一個(gè)類似于map集合的ThreadLocal類,它的內(nèi)部存在<Thread.currentThread,Connection>的鍵值對(duì)音婶,通過(guò)它保證獲取同一個(gè)connection連接慨畸。


    public class JDBCUtils {
        private static DataSource dataSource = new ComboPooledDataSource();
        private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
    
        // 獲取連接池對(duì)象
        public static DataSource getDataSource() {
            return dataSource;
        }
    
        // 提供連接
        public static Connection getConnection() throws SQLException {
            return dataSource.getConnection();
        }
    
        // 提供連接,從ThreadLocal中獲取的
        public static Connection getConnectionTL() throws SQLException {
            // 從ThreadLocal中獲取連接
            Connection connection = threadLocal.get();
            // 如果連接對(duì)象為空
            if (connection == null) {
                // 從連接池獲取連接
                connection = getConnection();
                // 將連接放入ThreadLocal,這樣下一次從ThreadLocal中獲取的時(shí)候就有數(shù)據(jù)了
                threadLocal.set(connection);
            }
    
            return connection;
        }
    
        // 開啟事務(wù)
        public static void startTransaction() throws SQLException {
            Connection connection = getConnectionTL();
            connection.setAutoCommit(false);
    
        }
    
        // 提交事務(wù)并釋放資源
        public static void commitAndRelease() throws SQLException {
            Connection connection = getConnectionTL();
            // 提交事務(wù)
            connection.commit();
            if (connection != null) {
                connection.close();
                connection = null;
            }
            // 把連接對(duì)象和ThreadLocal解綁,可以讓ThreadLocal盡快被釋放,節(jié)約服務(wù)器內(nèi)存資源
            threadLocal.remove();
    
        }
    
        // 回滾事務(wù)并釋放資源
        public static void rollbackAndRelease() throws SQLException {
            Connection connection = getConnectionTL();
            // 回滾事務(wù)
            connection.rollback();   
            if (connection != null) {   
                connection.close();
                connection = null;
            }
            // 把連接對(duì)象和ThreadLocal解綁,可以讓ThreadLocal盡快被釋放,節(jié)約服務(wù)器內(nèi)存資源
            threadLocal.remove();
    
        }
    
    }

3.6、 案例實(shí)現(xiàn)_為什么要使用事務(wù)衣式?

  • 如果不考慮事務(wù),會(huì)導(dǎo)致轉(zhuǎn)賬錢丟失的問題.所以必須考慮事務(wù)

  • 如果要避免上述問題,只需要保證所有的操作使用同一個(gè)連接對(duì)象即可

  • 解決方法

    • 傳遞參數(shù)Connection(打破了三層架構(gòu),因此采用線程綁定)
    • 線程綁定ThreadLocal
  • ThreadLocal簡(jiǎn)介

    • 作用 : 把一個(gè)操作對(duì)象和當(dāng)前線程綁定在一起. 其內(nèi)部維護(hù)了一個(gè)Map集合.key就是當(dāng)前線程,value就是要綁定的內(nèi)容
    • 常用API
      • set(T value) : 把一個(gè)對(duì)象和當(dāng)前線程進(jìn)行綁定.等價(jià)于Map.put(Thread.currentThread(),value)
      • T get() : 獲取和當(dāng)前線程綁定在一起的對(duì)象.等價(jià)于Map.get(Thread.currentThread())
      • remove() : 移除和當(dāng)前線程綁定在一起的對(duì)象.等價(jià)于Map.remove(Thread.currentThread())
![img03.png](http://upload-images.jianshu.io/upload_images/5303154-013edb1268a6c647.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

4寸士、事務(wù)的一些概念

事務(wù)特性

  • <font color='red'>事務(wù)的四大特性:

    • 原子性(Atomicity):事務(wù)的一組操作不可分割檐什,要么都成功,要么都失敗
    • 一致性(Consistency):事務(wù)前后數(shù)據(jù)保持完整性.轉(zhuǎn)賬前A和B賬戶總和2000元弱卡,轉(zhuǎn)賬后總和還是2000 元
    • 隔離性(Isolation):并發(fā)訪問時(shí),事務(wù)之間是隔離的,一個(gè)事務(wù)不應(yīng)該影響其它事務(wù)的運(yùn)行效果
    • 持久性(Durability):當(dāng)事務(wù)一旦提交,事務(wù)數(shù)據(jù)永久存在,無(wú)法改變 </font>
  • 企業(yè)開發(fā)中一定要保證事務(wù)原子性

  • 事務(wù)最復(fù)雜問題都是由事務(wù)隔離性引起的

隔離性

  • 不考慮事務(wù)隔離將引發(fā)的問題

    • 臟讀:一個(gè)事務(wù)讀取另一個(gè)事務(wù)未提交的數(shù)據(jù).這是數(shù)據(jù)庫(kù)隔離中最重要的問題
    • 不可重復(fù)讀:一個(gè)事務(wù)讀取另一個(gè)事務(wù)已提交的數(shù)據(jù)乃正,在一個(gè)事務(wù)中兩次查詢結(jié)果不同(針對(duì)update操作)
    • 虛讀:一個(gè)事務(wù)讀取另一個(gè)事務(wù)插入的數(shù)據(jù),造成在一個(gè)事務(wù)中兩次查詢記錄條數(shù)不同(針對(duì)insert操作)
  • 數(shù)據(jù)庫(kù)為了解決三類隔離引發(fā)問題,提供了四個(gè)數(shù)據(jù)庫(kù)隔離級(jí)別(所有數(shù)據(jù)庫(kù)通用)

    • <font color='red'> Serializable : 串行處理.可以解決三類問題
    • Repeatable read :可以解決不可重復(fù)讀婶博、臟讀瓮具,但是會(huì)發(fā)生虛讀.是MySQL的默認(rèn)級(jí)別
    • read committed : 可以解決臟讀,會(huì)發(fā)生不可重復(fù)讀、虛讀.是Oracle的默認(rèn)級(jí)別
    • read uncommitted : 會(huì)導(dǎo)致三類問題發(fā)生 </font>
    • 按照隔離級(jí)別從高到低排序 : Serializable > Repeatable read > read committed > read uncommitted
    • 數(shù)據(jù)庫(kù)隔離問題危害的排序 : 臟讀> 不可重復(fù)讀 > 虛讀
    • 多數(shù)數(shù)據(jù)庫(kù)廠商都會(huì)采用Repeatable read或read committed兩個(gè)級(jí)別.
  • 更改事務(wù)隔離級(jí)別的語(yǔ)句

    • set transaction isolation level 設(shè)置事務(wù)隔離級(jí)別
    • select @@tx_isolation; 查詢當(dāng)前事務(wù)隔離級(jí)別

隔離級(jí)別引發(fā)問題的小實(shí)驗(yàn)

  • 臟讀問題(read uncommitted)

    • 開啟兩個(gè)窗口,執(zhí)行一次查詢,獲得一個(gè)結(jié)果
    • 將B窗口隔離級(jí)別設(shè)置為read uncommitted
      • set session transaction isolation level read uncommitted;
    • 在A凡人、B窗口分別開啟一個(gè)事務(wù) start transaction;
    • 在A窗口完成轉(zhuǎn)賬操作
      • update account set money= money - 200 where name='aaa';
      • update account set money= money +200 where name='bbb';
    • 在B窗口進(jìn)行查詢,會(huì)讀取到A窗口未提交的轉(zhuǎn)賬結(jié)果
    • A窗口進(jìn)行回滾rollback, B窗口查詢結(jié)果恢復(fù)之前
  • 不可重復(fù)讀(read committed)

    • 開啟兩個(gè)窗口,執(zhí)行一次查詢,獲得一個(gè)結(jié)果
    • 將B窗口隔離級(jí)別設(shè)置為read committed
      • set session transaction isolation level read committed;
    • 在A名党、B窗口分別開啟一個(gè)事務(wù) start transaction;
    • 在A窗口完成轉(zhuǎn)賬操作
      • update account set money= money - 200 where name='aaa';
      • update account set money= money +200 where name='bbb';
    • 此時(shí)在B窗口執(zhí)行查詢操作,數(shù)據(jù)不會(huì)發(fā)生改變.避免了臟讀問題
    • A窗口執(zhí)行commit,B窗口再次執(zhí)行查詢,會(huì)讀取到A窗口提交的結(jié)果.注意此時(shí)B窗口沒有提交事務(wù),也就是在同一事務(wù)中,讀取到了兩個(gè)結(jié)果.發(fā)生不可重復(fù)讀問題
  • 虛讀(Repeatable read)

    • 開啟兩個(gè)窗口,執(zhí)行一次查詢,獲得一個(gè)結(jié)果
    • 將B窗口隔離級(jí)別設(shè)置為Repeatable read
      • set session transaction isolation level repeatable read;
    • 在A、B窗口分別開啟一個(gè)事務(wù) start transaction;
    • 在A窗口完成轉(zhuǎn)賬操作
      • update account set money= money - 200 where name='aaa';
      • update account set money= money +200 where name='bbb';
    • 此時(shí)在B窗口執(zhí)行查詢操作,數(shù)據(jù)不會(huì)發(fā)生改變.避免了臟讀問題
    • A窗口執(zhí)行commit,B窗口再次執(zhí)行查詢,數(shù)據(jù)仍然不會(huì)發(fā)生改變.避免了不可重復(fù)讀.
    • 此時(shí)如果在A窗口插入一條數(shù)據(jù),而B窗口可以查詢到,就是發(fā)生了虛讀問題.但是這種情況發(fā)生的幾率非常小.
  • Serializable

    • 開啟兩個(gè)窗口,執(zhí)行一次查詢,獲得一個(gè)結(jié)果
    • 將B窗口隔離級(jí)別設(shè)置為read serializable
      • set session transaction isolation level serializable;
    • 在A挠轴、B窗口分別開啟一個(gè)事務(wù) start transaction;
    • 在B窗口執(zhí)行查詢操作
    • 在A窗口執(zhí)行插入操作.此時(shí)A窗口將會(huì)被卡住,不會(huì)執(zhí)行語(yǔ)句.直到B窗口提交或回滾,釋放數(shù)據(jù)庫(kù)資源
  • 在JDBC中,可以通過(guò)Connection.setTransactionIsolation(int level) 來(lái)設(shè)置隔離級(jí)別.如果沒有設(shè)置.會(huì)采用數(shù)據(jù)庫(kù)的默認(rèn)級(jí)別

丟失更新問題和悲觀鎖樂觀鎖機(jī)制【了解】

  • 事務(wù)丟失更新問題 : 兩個(gè)事務(wù)同時(shí)讀取同一條記錄传睹,A先修改記錄,B也修改記錄(B不知道A修改過(guò))忠荞,B提交數(shù)據(jù)后B的修改結(jié)果覆蓋了A的修改結(jié)果蒋歌。

  • 解決丟失更新的兩種方式

    • 事務(wù)和鎖是不可分開的,鎖一定是在事務(wù)中使用 委煤,當(dāng)事務(wù)關(guān)閉鎖自動(dòng)釋放
    • 悲觀鎖
      • 假設(shè)丟失更新會(huì)發(fā)生
      • 使用數(shù)據(jù)庫(kù)內(nèi)部鎖機(jī)制堂油,進(jìn)行表的鎖定,在A修改數(shù)據(jù)時(shí)碧绞,A就將數(shù)據(jù)鎖定府框,B此時(shí)無(wú)法進(jìn)行修改
      • 在mysql中默認(rèn)情況下,當(dāng)你修改數(shù)據(jù)讥邻,自動(dòng)為數(shù)據(jù)加鎖(在事務(wù)中),防止兩個(gè)事務(wù)同時(shí)修改數(shù)據(jù)
      • 在mysql內(nèi)部有兩種常用鎖
        • 讀鎖(共享鎖)
          • 一張表可以添加多個(gè)讀鎖迫靖,如果表被添加了讀鎖(不是當(dāng)前事務(wù)添加的),該表不可以修改
          • 語(yǔ)法 : select * from account lock in share mode;
          • 共享鎖非常容易發(fā)生死鎖
        • 寫鎖(排它鎖)
          • 一張表只能加一個(gè)排它鎖兴使,排他鎖和其它共享鎖系宜、排它鎖都具有互斥效果 。
          • 如果一張表想添加排它鎖发魄,前提是之前表一定沒有加過(guò)共享鎖和排他鎖
          • 語(yǔ)法 : select * from account for update ;
    • 樂觀鎖
      • 假設(shè)丟失更新不會(huì)發(fā)生
      • 使用的不是數(shù)據(jù)庫(kù)鎖機(jī)制盹牧,而是一個(gè)特殊標(biāo)記字段 : 數(shù)據(jù)庫(kù)timestamp 時(shí)間戳字段
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市励幼,隨后出現(xiàn)的幾起案子汰寓,更是在濱河造成了極大的恐慌,老刑警劉巖苹粟,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件有滑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡嵌削,警方通過(guò)查閱死者的電腦和手機(jī)毛好,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門望艺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人肌访,你說(shuō)我怎么就攤上這事荣茫。” “怎么了场靴?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵啡莉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我旨剥,道長(zhǎng)咧欣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任轨帜,我火速辦了婚禮魄咕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚌父。我一直安慰自己哮兰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布苟弛。 她就那樣靜靜地躺著喝滞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪膏秫。 梳的紋絲不亂的頭發(fā)上右遭,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天,我揣著相機(jī)與錄音缤削,去河邊找鬼窘哈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛亭敢,可吹牛的內(nèi)容都是我干的滚婉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼帅刀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼让腹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起劝篷,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤哨鸭,失蹤者是張志新(化名)和其女友劉穎民宿,沒想到半個(gè)月后娇妓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡活鹰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年哈恰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了只估。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡着绷,死狀恐怖蛔钙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荠医,我是刑警寧澤吁脱,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站彬向,受9級(jí)特大地震影響兼贡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜娃胆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一遍希、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧里烦,春花似錦凿蒜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至丧蘸,卻和暖如春虱饿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背触趴。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工氮发, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冗懦。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓爽冕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親披蕉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子颈畸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

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

  • 當(dāng)一個(gè)系統(tǒng)訪問量上來(lái)的時(shí)候爬凑,不只是數(shù)據(jù)庫(kù)性能瓶頸問題了徙缴,數(shù)據(jù)庫(kù)數(shù)據(jù)安全也會(huì)浮現(xiàn),這時(shí)候合理使用數(shù)據(jù)庫(kù)鎖機(jī)制就顯得異...
    JackFrost_fuzhu閱讀 7,712評(píng)論 4 83
  • 問題:事務(wù)是什么嘁信,有什么用? 事務(wù)就是一個(gè)事情于样,組成這個(gè)事情可能有多個(gè)單元疏叨,要求這些單元,要么全都成功穿剖,要么全都不...
    yeller閱讀 743評(píng)論 0 0
  • 當(dāng)一個(gè)系統(tǒng)訪問量上來(lái)的時(shí)候蚤蔓,不只是數(shù)據(jù)庫(kù)性能瓶頸問題了,數(shù)據(jù)庫(kù)數(shù)據(jù)安全也會(huì)浮現(xiàn)糊余,這時(shí)候合理使用數(shù)據(jù)庫(kù)鎖機(jī)制就顯得異...
    初來(lái)的雨天閱讀 3,553評(píng)論 0 22
  • 本文包括:1秀又、事務(wù)概念2、MySQL管理事務(wù)3贬芥、JDBC控制事務(wù)進(jìn)程4涮坐、事務(wù)的特性(ACID)5、事務(wù)的隔離級(jí)別6...
    廖少少閱讀 825評(píng)論 0 3
  • hibernate(20170731) 1.導(dǎo)包:hibernate-distribution-3.5.6-Fin...
    瀟湘雨smile閱讀 533評(píng)論 0 0