色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 數據庫事務,Connection連接池

數據庫事務,Connection連接池 時間:2018-09-27      來源:未知

一 事務

   (一)事務的概念

          事務指邏輯上一組操作,組成這組操作的各個單元,要么全部成功要么全部不成功。  例如:A--B轉賬,對應如下的兩條sql語句:

Update account set money = money-100 where name=’a’;;

Update account set money = money+100 where name=’b’;

數據庫默認事務時自動提交的,也就是發一條sql它就執行一條,如果想多條sql放在一個事務中,需要如下。

   (二)數據庫開啟事務cmd命令

開啟事務:start transaction

回退事務:rollback

提交事務:commit

   (三)JDBC開啟事務

         1.一般事務

         conn.setAutoCommit(false);//設置事務不自動提交。

Conn.commit();//后提價事務。

Conn.rollback();//出現異常,回退事務。 

Connection conn=null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            conn = DriverManager.getConnection
            ("jdbc:mysql://localhost:3306/mytransation", "root", "root");
            //設置不自動提交
            conn.setAutoCommit(false);
            ps = conn.prepareStatement("update account set money=money-100 where name=?");
            ps.setString(1, "a");
            ps.executeUpdate();
            //假設異常點
            /*int a=1/0;*/
            ps = conn.prepareStatement("update account set money=money+100 where name=?");
            ps.setString(1,"b");
            ps.executeUpdate();
            //在這里提交事務
            conn.commit();
        }
        catch(Exception e){
            try {
//出現異常回退事務
if(conn!=null)
                conn.rollback();
                System.out.println("出現異常,事務回退");
            } catch (SQLExcep tion e2) {
                e2.printStackTrace();
            }
            System.out.println(e.getMessage());
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                    System.out.println("Connection異常");
                } finally{
                    conn = null;
                }

        2.設置回滾點提交事務,提交異常之前的sql語句 
Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Savepoint sp = null;
       
        try{
            conn = DriverManager.getConnection("jdbc:mysql:///mytransation", "root", "root");
           
            conn.setAutoCommit(false);//設置不自動提交事務
            ps = conn.prepareStatement("update account set money=money-100 where name=?");
            ps.setString(1, "a");
            ps.executeUpdate();
           
            ps = conn.prepareStatement("update account set money=money+100 where name=?");
            ps.setString(1,"b");
            ps.executeUpdate();
           
            sp = conn.setSavepoint();//設置回滾點
           
            ps = conn.prepareStatement("update account set money=money-100 where name=?");
            ps.setString(1, "a");
            ps.executeUpdate();
           
            int a=1/0;//模擬異常
           
            ps = conn.prepareStatement("update account set money=money+100 where name=?");
            ps.setString(1,"b");
            ps.executeUpdate();
           
            conn.commit();//提交事務
        } catch(Exception e){
            try{
                if(conn !=null){//如果sp為空,則在回滾點之前回退模式
                    if(sp == null){
                        conn.rollback();
                    }else{//否則回滾到回滾點的數據,讓其提交。
                        conn.rollback(sp);
                        conn.commit();
                    }
                }
            }
            catch(SQLException e1){
            }
        }

3.事務的四大特性(ACID,很重要)。

          原子性(Atomicity):事務時一個不可分割的工作單位,事務中操作 要么發生,要么都不發生。

          一致性(Consistency):事務前后數據的完整性必須保持一致。

          隔離性(Isolation):多個用戶并發訪問數據庫時,一個用戶的事務不能被其他用戶的事務所干擾。多個并發事務之間數據要相互隔離。

          持久性(Durability):事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響。

          如果不考慮事務的隔離性,會出現的問題:

          (1)臟讀:一個事務讀取到另外一個事務的未提交的數據

          (2)不可重復讀: 同一個數據(表)不可重復讀(針對于update更新數據)

          (3)虛讀:同一數據(表)不可重復讀(強調insert)

          (4)丟失更新:

         4.隔離級別以及隔離級別的設置

            (1)隔離級別

                 Read uncommitted   數據庫不能防止臟讀、不可重復讀、虛讀。

                 Read committed(oracle)  能防止臟讀,不能防止不可重復讀、虛讀。

                 Repeatable read(mysql) 能防止臟讀、不可重復讀,不能防止虛讀。

                 Serializable  單線程數據庫,能防止所有的問題。

                 性能分析:read uncommitted>read committed>repeatable read>serializable

                 安全性能:serializable>repeatable read>read committed>read uncommitted

            (2)隔離級別的設置

                 1)cmd操作命令

                    Select  @@tx_isolation 查詢當前事務隔離級別

                    Set session transaction isolation level 設置的事務級別

                 2)JDBC中操作隔離級別

 

Connection的實例方法setTransactionIsolation(int level)

可以的值是(Connection的靜態常量):

 TRANSACTION_READ_UNCOMMITTED(不能防止臟讀,不可重復讀,虛讀)

 TRANSACTION_READ_COMMITTED(能防止臟讀,不能解決不可重復讀,虛讀)

 TRANSACTION_REPEATABLE_READ(能防止臟讀,不可重復讀,不能解決虛讀)

 TRANSACTION_SERIALIZABLE(可以解決所有的問題)

        

          5.臟讀、不可重復讀、虛讀案例演示。

    

            (1)臟讀演示

                 一開始狀態:A賬戶:1000元

                             B 賬戶:1000元

                 A賬戶向B賬戶匯款的情況:

                    start  transaction

                    Update account set money=money-100 where name=’A’;

                    Update account set money=money+100 where name=’B’;

                    -------此時B查詢,設置隔離級別為read uncommitted

                         Select  * from account where name=’B’;結果為1100;

                    Rollback;回滾事務,數據并未修改成功。

(2)不可重復讀的

 a 賬戶三個月工資為:1000,1000,1000

   Start transaction

Select sum(money) from account where name=’a’;

-------此時 財務b,將第一個月工資修改為1300,并且立即提交,即

Update account set money=1300 where name=’a’;

Select sum(money)/count(*)  from account where name=’a’;提交,發現報表不對。

(3)虛讀

         6.轉賬小案例,事務控制。

                1)邏輯層(service)調用dao層的兩個方法(一個轉入方法,一個轉出方法),解決其中一個方法失敗,因此需要事務控制,事務回滾等。

                2)用到事務,那么就應該使用同一個Connection對象,因此,在service層的方法里,應該共用一個Connection對象。

                3)mysql,修改不存在的用戶名的賬戶值返回值代表影響的行數,由此可以找到解決該方法的問題。

               4)學會使用同一個ThreadLocal,可以理解為同一個線程的容器,只要在同一個線程,就可以取出來使用。示例:

Private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

Public static Connection getCon(){

   If(tl.get==null){

   Tl.set(DriverManager.getConnection(“”,””,””));

 }

Return tl.get();

}

    7.數據丟失更新。

1)數據丟失更新示意圖(多個事務對同一行數據進行操作,后提交的事務將覆蓋先提交的事務)。

 

        

   2)數據更新丟失的解決方法

         (1)悲觀鎖(假設丟失更新一定發生,利用數據庫內部鎖機制)

              共享鎖:

              Select  * from account lock in share mode(讀鎖,共享鎖)

                       排它鎖(被鎖中的可以是一行數據,也可以是整張表):

  Select * from account for update(寫鎖,排它鎖)。

Update 默認是排他鎖。

(2)樂觀鎖(加鎖丟失更新不會發生,采用程序中添加版本字段解決丟失更新問題)

     create table product (

  id int,

  name varchar(20),

  updatetime timestamp

);

 

insert into product values(1,'冰箱',null);

update product set name='洗衣機' where id = 1;

 

解決丟失更新:在數據表添加版本字段,每次修改過記錄后,版本字段都會更新,如果讀取是版本字段,與修改時版本字段不一致,說明別人進行修改過數據 (重改)

8.數據庫連接池

   (1)定義:創建一個容器,這個容器來裝多個Connection對象,在使用該對象的時候,從容器獲取一個Connection對象,使用完畢后,再把這個Connection對象重新裝到容器當中。那么這個容器就叫做數據庫連接池。

(2)自定義連接池

     步驟:1.創建一個MyDataSource類,在這個類中創建一個LinkedList<Connection>

2.在構造器方法中初始化List集合,并向其中裝入5個Connection對象

3.創建一個public Connection getConnection();從List集合中獲取一個連接對象返回

4.創建一個Public void readdd(Connetion)這個方法是將使用完成后的Connection對象重新裝到List集合中。

   代碼問題:

                        1.連接池的創建時有標準的,在javax.sql包下定義一個接口DataSource,我們必須實現

  2.改變Connection的close()方法,不是銷毀它,而是將它重新裝入到連接池中。解決這      

                          個問題本質就是將Connection的close()行為改變。

  三種方式改變方法行為:繼承;裝飾者模式;動態代理   

               (3)使用開源連接池

   1.dbcp(DataBase Connection Pool)

Dbcp是Apache下的一個開源連接池,兩個關鍵.jar包(commons-dbcp-1.4.jar和commons-pool-1.5.6.jar)

1)手動配置

BasicDataSource bds = new BasicDataSource();
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setUrl("jdbc:mysql:///mytransation");
        bds.setUsername("root");
        bds.setPassword("root");
        Connection con = bds.getConnection();
        ResultSet rs = con.prepareStatement("select * from account").executeQuery();
        while(rs.next()){
            System.out.println("賬戶:"+rs.getString("name")+",余額:"+rs.getDouble("money"));
        }
        JDBCUtils.closeRS(rs);
        con.close();//不是關閉連接,而是放回連接池

  2)自動配置

  Properties p = new Properties();

        p.load(new FileInputStream("D:\\Myeclipse java程序\\AccountTransaction\\src\\dbcp.properties"));
/*      p.setProperty("url", "jdbc:mysql:///mytransation");
        p.setProperty("username", "root");
        p.setProperty("password", "root");
        p.setProperty("driverClassName", "com.mysql.jdbc.Driver");*/
        DataSource ds = BasicDataSourceFactory.createDataSource(p);
        Connection con = ds.getConnection();
        ResultSet rs = con.prepareStatement("select * from account").executeQuery();
        while(rs.next()){
            System.out.println("賬戶:"+rs.getString("name")+",余額:"+rs.getDouble("money"));
        }
        JDBCUtils.closeRS(rs);
        con.close();//不是關閉連接,而是放回連接池

2.c3p0 (重點,是一個開源數JDBC連接池,實現數據源和JNDI綁定,支持JDBC3和JDBC2的標準擴展。使用它的開源項目有Hibernate,Spring等。性能更強,擁有自動回收空閑連接功能)    

  1)手動配置

ComboPooledDataSource cpds = new ComboPooledDataSource();
        cpds.setDriverClass("com.mysql.jdbc.Driver");
        cpds.setJdbcUrl("jdbc:mysql:///mytransation");
        cpds.setUser("root");
        cpds.setPassword("root");
        Connection con = cpds.getConnection();
        ResultSet rs = con.prepareStatement("select * from account").executeQuery();
        while(rs.next()){
            System.out.println("賬戶:"+rs.getString("name")+",余額:"+rs.getDouble("money")+"c3p0hand");
        }
        JDBCUtils.closeRS(rs);
        con.close();//不是關閉連接,而是放回連接池

        2)自動配置

C3p0的配置文件可以是properties也可以是xml,對應的文件名是c3p0.properties或者c3p0-config.xml,要求放在classpath路徑下(也就是web應用的classes目錄),我們放在src目錄下即可。

使用:ComboPooledDataSource cpds = new ComboPooledDataSource();

   Xml文件形式:

       <?xml version="1.0" encoding="UTF-8"?>

<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///mytransation</property>
        <property name="user">root</property>
        <property name="password">root</property>
    </default-config>
</c3p0-config>

Properties形式:

 

                 (4)tomcat內置連接池(測試出來!!)

Tomcat連接池用的是dbcp。

1)tomcat怎樣管理連接池

   要想將一個dbcp連接池讓tomcat管理,只需要創建一個context.xml配置文件,在配置文件中配置相關信息。

<Context>

<Resource  name=”jdbc/EmployeeDB” auth=”Container”

        Type=”javax.sql.DataSource” username=”root” password=”root”

     driverClassName=”com.mysql.jdbc.Driver” url=”jdbc:mysql:///mytransat”

                                   maxActive=”8” maxIdle=”4”

/>

</Context>

問題:context.xml文件的配置位置:

      (1)在tomcat/conf/context.xml 這個連接池是給整個服務器用的(全局)

      (2)在tomcat/conf/Catalina/localhost 連接池只給localhost虛擬主機使用(全局)。

(3)將其配置在web應用的META-INF下。

注意:如果是全局設置,那么需要將數據庫驅動放置在tomcat/lib目錄下。

問題:怎么從tomcat獲取鏈接池對象?

Context context = new InitialContext();

Context envCtx = (Context) context.lookup(“java:comp/env”);//固定路徑

DataSource ds = (DataSource)envCtx.lookup(“jdbc/EmployeeDB”);

.......操作Connection對象

上一篇:Android圖形圖像(三)繪圖

下一篇:JavaScript與HTML的結合方式

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 丰满少妇熟女高潮流白浆 | 日产精品一品二品三品 | 狠狠干| sifangtv国产在线 | 印度妓女野外xxww | 国产精品黄在线观看免费软件 | 无码午夜福利片在线观看 | 137日本免费肉体摄影 | 狠狠干2021 | 国产日韩欧美一区二区久久精品 | 日韩免费卡一卡二新区 | 国产AV一区二区三区日韩 | 无码毛片视频一区二区三区 | 色综合伊人丁香五月桃花婷婷 | 亚洲AV永久无无码精品一区二区三区 | 性裸交a片一区二区三区 | 后入内射国产一区二区 | 国产亚洲精品久久久久秋霞 | 亚洲 欧美 综合 在线 精品 | 午夜成人看特AAAA片视频 | 少妇高潮av久久久久久 | 专干老肥熟女视频 | 国产精品日本无码久久 | 精品熟女碰碰人人A久久 | 成人A级视频在线观看 | 无码熟熟妇丰满人妻啪啪 | 中文字幕在线亚洲二区 | 黑人又粗又大XXX精品 | 亚洲av日韩综合一区二区三区 | 日本 在线播放 | 99热这里只有精品国产免费免费 | 国产又粗又猛又大爽又黄 | 中国老太婆bbbbbxxxxx | 国产剧情av一区二区三区在线观看 | 一本色道久久88—综合亚洲精品 | 国产精品色情国产三级金瓶双艳 | 18禁黄网站禁片免费观看国产 | 成人免费A片在线看网站外卖员 | 亚洲欧洲AV综合色无码 | 精品人妻无码一区二区三区不卡 | 超清无码无卡中文字幕 |