国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 數(shù)據(jù)庫事務(wù),Connection連接池

數(shù)據(jù)庫事務(wù),Connection連接池 時間:2018-09-27      來源:未知

一 事務(wù)

   (一)事務(wù)的概念

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

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

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

數(shù)據(jù)庫默認(rèn)事務(wù)時自動提交的,也就是發(fā)一條sql它就執(zhí)行一條,如果想多條sql放在一個事務(wù)中,需要如下。

   (二)數(shù)據(jù)庫開啟事務(wù)cmd命令

開啟事務(wù):start transaction

回退事務(wù):rollback

提交事務(wù):commit

   (三)JDBC開啟事務(wù)

         1.一般事務(wù)

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

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

Conn.rollback();//出現(xiàn)異常,回退事務(wù)。 

Connection conn=null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            conn = DriverManager.getConnection
            ("jdbc:mysql://localhost:3306/mytransation", "root", "root");
            //設(shè)置不自動提交
            conn.setAutoCommit(false);
            ps = conn.prepareStatement("update account set money=money-100 where name=?");
            ps.setString(1, "a");
            ps.executeUpdate();
            //假設(shè)異常點(diǎn)
            /*int a=1/0;*/
            ps = conn.prepareStatement("update account set money=money+100 where name=?");
            ps.setString(1,"b");
            ps.executeUpdate();
            //在這里提交事務(wù)
            conn.commit();
        }
        catch(Exception e){
            try {
//出現(xiàn)異;赝耸聞(wù)
if(conn!=null)
                conn.rollback();
                System.out.println("出現(xiàn)異常,事務(wù)回退");
            } 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.設(shè)置回滾點(diǎn)提交事務(wù),提交異常之前的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);//設(shè)置不自動提交事務(wù)
            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();//設(shè)置回滾點(diǎn)
           
            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();//提交事務(wù)
        } catch(Exception e){
            try{
                if(conn !=null){//如果sp為空,則在回滾點(diǎn)之前回退模式
                    if(sp == null){
                        conn.rollback();
                    }else{//否則回滾到回滾點(diǎn)的數(shù)據(jù),讓其提交。
                        conn.rollback(sp);
                        conn.commit();
                    }
                }
            }
            catch(SQLException e1){
            }
        }

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

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

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

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

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

          如果不考慮事務(wù)的隔離性,會出現(xiàn)的問題:

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

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

          (3)虛讀:同一數(shù)據(jù)(表)不可重復(fù)讀(強(qiáng)調(diào)insert)

          (4)丟失更新:

         4.隔離級別以及隔離級別的設(shè)置

            (1)隔離級別

                 Read uncommitted   數(shù)據(jù)庫不能防止臟讀、不可重復(fù)讀、虛讀。

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

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

                 Serializable  單線程數(shù)據(jù)庫,能防止所有的問題。

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

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

            (2)隔離級別的設(shè)置

                 1)cmd操作命令

                    Select  @@tx_isolation 查詢當(dāng)前事務(wù)隔離級別

                    Set session transaction isolation level 設(shè)置的事務(wù)級別

                 2)JDBC中操作隔離級別

 

Connection的實(shí)例方法setTransactionIsolation(int level)

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

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

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

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

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

        

          5.臟讀、不可重復(fù)讀、虛讀案例演示。

    

            (1)臟讀演示

                 一開始狀態(tài):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查詢,設(shè)置隔離級別為read uncommitted

                         Select  * from account where name=’B’;結(jié)果為1100;

                    Rollback;回滾事務(wù),數(shù)據(jù)并未修改成功。

(2)不可重復(fù)讀的

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

   Start transaction

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

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

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

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

(3)虛讀

         6.轉(zhuǎn)賬小案例,事務(wù)控制。

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

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

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

               4)學(xué)會使用同一個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.數(shù)據(jù)丟失更新。

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

 

        

   2)數(shù)據(jù)更新丟失的解決方法

         (1)悲觀鎖(假設(shè)丟失更新一定發(fā)生,利用數(shù)據(jù)庫內(nèi)部鎖機(jī)制)

              共享鎖:

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

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

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

Update 默認(rèn)是排他鎖。

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

     create table product (

  id int,

  name varchar(20),

  updatetime timestamp

);

 

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

update product set name='洗衣機(jī)' where id = 1;

 

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

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

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

(2)自定義連接池

     步驟:1.創(chuàng)建一個MyDataSource類,在這個類中創(chuàng)建一個LinkedList<Connection>

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

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

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

   代碼問題:

                        1.連接池的創(chuàng)建時有標(biāo)準(zhǔn)的,在javax.sql包下定義一個接口DataSource,我們必須實(shí)現(xiàn)

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

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

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

               (3)使用開源連接池

   1.dbcp(DataBase Connection Pool)

Dbcp是Apache下的一個開源連接池,兩個關(guān)鍵.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();//不是關(guān)閉連接,而是放回連接池

  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();//不是關(guān)閉連接,而是放回連接池

2.c3p0 (重點(diǎn),是一個開源數(shù)JDBC連接池,實(shí)現(xiàn)數(shù)據(jù)源和JNDI綁定,支持JDBC3和JDBC2的標(biāo)準(zhǔn)擴(kuò)展。使用它的開源項(xiàng)目有Hibernate,Spring等。性能更強(qiáng),擁有自動回收空閑連接功能)    

  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();//不是關(guān)閉連接,而是放回連接池

        2)自動配置

C3p0的配置文件可以是properties也可以是xml,對應(yīng)的文件名是c3p0.properties或者c3p0-config.xml,要求放在classpath路徑下(也就是web應(yīng)用的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內(nèi)置連接池(測試出來。。

Tomcat連接池用的是dbcp。

1)tomcat怎樣管理連接池

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

<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 這個連接池是給整個服務(wù)器用的(全局)

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

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

注意:如果是全局設(shè)置,那么需要將數(shù)據(jù)庫驅(qū)動放置在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的結(jié)合方式

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部