[MySql 三] 事務(wù)&數(shù)據(jù)庫(kù)連接池&DBUtils

1. 事務(wù)

Transaction 其實(shí)指的一組操作柱恤,里面包含許多個(gè)單一的邏輯。只要有一個(gè)邏輯沒(méi)有執(zhí)行成功找爱,那么都算失敗梗顺。 所有的數(shù)據(jù)都回歸到最初的狀態(tài)(回滾)

  • 為什么要有事務(wù)?

為了確保邏輯的成功。 例子: 銀行的轉(zhuǎn)賬车摄。

1.1 使用命令行方式演示事務(wù)寺谤。

  • 開(kāi)啟事務(wù)
start transaction;
  • 提交或者回滾事務(wù)
commit; 提交事務(wù), 數(shù)據(jù)將會(huì)寫(xiě)到磁盤(pán)上的數(shù)據(jù)庫(kù)
rollback ;  數(shù)據(jù)回滾吮播,回到最初的狀態(tài)变屁。
  1. 關(guān)閉自動(dòng)提交功能。


    img01.png
  2. 演示事務(wù)


    img02.png

1.2 使用代碼方式演示事務(wù)

代碼里面的事務(wù)意狠,主要是針對(duì)連接來(lái)的粟关。

  1. 通過(guò)conn.setAutoCommit(false )來(lái)關(guān)閉自動(dòng)提交的設(shè)置。
  2. 提交事務(wù) conn.commit();
  3. 回滾事務(wù) conn.rollback();
@Test
    public void testTransaction(){
        
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtil.getConn();
            
            //連接环戈,事務(wù)默認(rèn)就是自動(dòng)提交的闷板。 關(guān)閉自動(dòng)提交。
            conn.setAutoCommit(false);
            
            String sql = "update account set money = money - ? where id = ?";
            ps = conn.prepareStatement(sql);
            
            //扣錢(qián)院塞, 扣ID為1 的100塊錢(qián)
            ps.setInt(1, 100);
            ps.setInt(2, 1);
            ps.executeUpdate();
            
            
            int a = 10 /0 ;
            
            //加錢(qián)遮晚, 給ID為2 加100塊錢(qián)
            ps.setInt(1, -100);
            ps.setInt(2, 2);
            ps.executeUpdate();
            
            //成功: 提交事務(wù)。
            conn.commit();
            
        } catch (SQLException e) {
            try {
                //事變: 回滾事務(wù)
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
            
        }finally {
            JDBCUtil.release(conn, ps, rs);
        }
    }

1.3 事務(wù)的特性

  • 原子性

指的是 事務(wù)中包含的邏輯拦止,不可分割县遣。

  • 一致性

指的是 事務(wù)執(zhí)行前后。數(shù)據(jù)完整性

  • 隔離性

指的是 事務(wù)在執(zhí)行期間不應(yīng)該受到其他事務(wù)的影響

  • 持久性

指的是 事務(wù)執(zhí)行成功创泄,那么數(shù)據(jù)應(yīng)該持久保存到磁盤(pán)上艺玲。

1.4 事務(wù)的安全隱患

不考慮隔離級(jí)別設(shè)置,那么會(huì)出現(xiàn)以下問(wèn)題鞠抑。

  • 臟讀:一個(gè)事務(wù)讀到另外一個(gè)事務(wù)還未提交的數(shù)據(jù)。
  • 不可重復(fù)讀:一個(gè)事務(wù)讀到了另外一個(gè)事務(wù)提交的數(shù)據(jù) 忌警,造成了前后兩次查詢結(jié)果不一致搁拙。
  • 幻讀:一個(gè)事務(wù)讀到了另一個(gè)事務(wù)insert的數(shù)據(jù) 秒梳,造成前后查詢結(jié)果不一致 。

寫(xiě)

  • 丟失更新

1.5 可串行化

如果有一個(gè)連接的隔離級(jí)別設(shè)置為了串行化 箕速,那么誰(shuí)先打開(kāi)了事務(wù)酪碘, 誰(shuí)就有了先執(zhí)行的權(quán)利, 誰(shuí)后打開(kāi)事務(wù)盐茎,誰(shuí)就只能得著兴垦,等前面的那個(gè)事務(wù),提交或者回滾后字柠,才能執(zhí)行探越。 但是這種隔離級(jí)別一般比較少用。 容易造成性能上的問(wèn)題窑业。 效率比較低钦幔。

1.6 總結(jié)

分類

  • 按效率劃分,從高到低

讀未提交 > 讀已提交 > 可重復(fù)讀 > 可串行化

  • 按攔截程度 常柄,從高到底

可串行化 > 可重復(fù)讀 > 讀已提交 > 讀未提交

問(wèn)題
讀未提交

引發(fā)問(wèn)題: 臟讀

讀已提交

解決: 臟讀 鲤氢, 引發(fā): 不可重復(fù)讀

可重復(fù)讀

解決: 臟讀 、 不可重復(fù)讀 西潘, 未解決: 幻讀

可串行化

解決: 臟讀卷玉、 不可重復(fù)讀 、 幻讀喷市。

mySql 默認(rèn)的隔離級(jí)別是 可重復(fù)讀
Oracle 默認(rèn)的隔離級(jí)別是 讀已提交

2. 數(shù)據(jù)庫(kù)連接池

2.1 DBCP

  1. 導(dǎo)入jar文件

不使用配置文件方式:

    public void testDBCP01(){
    
        
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            
            //1. 構(gòu)建數(shù)據(jù)源對(duì)象
            BasicDataSource dataSource = new BasicDataSource();
            //連的是什么類型的數(shù)據(jù)庫(kù)揍庄, 訪問(wèn)的是哪個(gè)數(shù)據(jù)庫(kù) , 用戶名东抹, 密碼蚂子。。
            //jdbc:mysql://localhost/bank 主協(xié)議:子協(xié)議 ://本地/數(shù)據(jù)庫(kù)
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost/bank");
            dataSource.setUsername("root");
            dataSource.setPassword("root");
            
            
            //2. 得到連接對(duì)象
            conn = dataSource.getConnection();
            String sql = "insert into account values(null , ? , ?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, "admin");
            ps.setInt(2, 1000);
            
            ps.executeUpdate();
            
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.release(conn, ps);
        }
        
    }

使用配置文件方式:

    Connection conn = null;
    PreparedStatement ps = null;
    try {
        BasicDataSourceFactory factory = new BasicDataSourceFactory();
        Properties properties = new Properties();
        InputStream is = new FileInputStream("src//dbcpconfig.properties");
        properties.load(is);
        DataSource dataSource = factory.createDataSource(properties);
        
        //2. 得到連接對(duì)象
        conn = dataSource.getConnection();
        String sql = "insert into account values(null , ? , ?)";
        ps = conn.prepareStatement(sql);
        ps.setString(1, "liangchaowei");
        ps.setInt(2, 100);
        
        ps.executeUpdate();
        
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        JDBCUtil.release(conn, ps);
    }

2.2 C3P0

1 .拷貝jar文件 到 lib目錄

不使用配置文件方式

    Connection conn = null;
    PreparedStatement ps = null;
    try {
        //1. 創(chuàng)建datasource
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //2. 設(shè)置連接數(shù)據(jù)的信息
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        
        //忘記了---> 去以前的代碼 ---> jdbc的文檔
        dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        
        //2. 得到連接對(duì)象
        conn = dataSource.getConnection();
        String sql = "insert into account values(null , ? , ?)";
        ps = conn.prepareStatement(sql);
        ps.setString(1, "admi234n");
        ps.setInt(2, 103200);
        
        ps.executeUpdate();
        
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        JDBCUtil.release(conn, ps);
    }

使用配置文件方式

        //默認(rèn)會(huì)找 xml 中的 default-config 分支缭黔。 
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        
        // 得到連接對(duì)象
        conn = dataSource.getConnection();
        String sql = "insert into account values(null , ? , ?)";
        ps = conn.prepareStatement(sql);
        ps.setString(1, "admi234n");
        ps.setInt(2, 103200);

3. DBUtils

3.1 增刪改

            //dbutils 只是幫我們簡(jiǎn)化了CRUD 的代碼食茎, 但是連接的創(chuàng)建以及獲取工作。 不在他的考慮范圍
    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());

    
    //增加
    //queryRunner.update("insert into account values (null , ? , ? )", "aa" ,1000);
    
    //刪除
    //queryRunner.update("delete from account where id = ?", 5);
    
    //更新
    //queryRunner.update("update account set money = ? where id = ?", 10000000 , 6);

3.2 查詢

  1. 直接new接口的匿名實(shí)現(xiàn)類
    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());


    Account  account =  queryRunner.query("select * from account where id = ?", new ResultSetHandler<Account>(){

        @Override
        public Account handle(ResultSet rs) throws SQLException {
            Account account  =  new Account();
            while(rs.next()){
                String name = rs.getString("name");
                int money = rs.getInt("money");
                
                account.setName(name);
                account.setMoney(money);
            }
            return account;
        }
         
     }, 6);
    
    System.out.println(account.toString());
  1. 直接使用框架已經(jīng)寫(xiě)好的實(shí)現(xiàn)類馏谨。
* 查詢單個(gè)對(duì)象

    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    //查詢單個(gè)對(duì)象
    Account account = queryRunner.query("select * from account where id = ?", 
            new BeanHandler<Account>(Account.class), 8);


* 查詢多個(gè)對(duì)象

    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    List<Account> list = queryRunner.query("select * from account ",
            new BeanListHandler<Account>(Account.class));

3.3 ResultSetHandler 常用的實(shí)現(xiàn)類

以下兩個(gè)是使用頻率最高的
BeanHandler, 查詢到的單個(gè)數(shù)據(jù)封裝成一個(gè)對(duì)象
BeanListHandler, 查詢到的多個(gè)數(shù)據(jù)封裝 成一個(gè)List<對(duì)象>


ArrayHandler, 查詢到的單個(gè)數(shù)據(jù)封裝成一個(gè)數(shù)組
ArrayListHandler, 查詢到的多個(gè)數(shù)據(jù)封裝成一個(gè)集合 别渔,集合里面的元素是數(shù)組。

MapHandler, 查詢到的單個(gè)數(shù)據(jù)封裝成一個(gè)map
MapListHandler,查詢到的多個(gè)數(shù)據(jù)封裝成一個(gè)集合 惧互,集合里面的元素是map哎媚。

ColumnListHandler
KeyedHandler
ScalarHandler

c3p0_demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市喊儡,隨后出現(xiàn)的幾起案子拨与,更是在濱河造成了極大的恐慌,老刑警劉巖艾猜,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件买喧,死亡現(xiàn)場(chǎng)離奇詭異捻悯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)淤毛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)今缚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人低淡,你說(shuō)我怎么就攤上這事姓言。” “怎么了蔗蹋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵何荚,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我纸颜,道長(zhǎng)兽泣,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任胁孙,我火速辦了婚禮唠倦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涮较。我一直安慰自己稠鼻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布狂票。 她就那樣靜靜地躺著候齿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闺属。 梳的紋絲不亂的頭發(fā)上慌盯,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音掂器,去河邊找鬼亚皂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛国瓮,可吹牛的內(nèi)容都是我干的灭必。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼乃摹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼禁漓!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起孵睬,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤播歼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后肪康,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體荚恶,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撩穿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年磷支,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谒撼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雾狈,死狀恐怖廓潜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情善榛,我是刑警寧澤辩蛋,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站移盆,受9級(jí)特大地震影響悼院,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咒循,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一据途、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叙甸,春花似錦颖医、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至僚祷,卻和暖如春佛致,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辙谜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工俺榆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筷弦。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓肋演,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親烂琴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爹殊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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