<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Cyh的博客

    Email:kissyan4916@163.com
    posts - 26, comments - 19, trackbacks - 0, articles - 220

    提交與回滾事務

    Posted on 2009-12-28 21:22 啥都寫點 閱讀(4198) 評論(0)  編輯  收藏 所屬分類: J2SE
         事務在提交前,所有的操作都是在虛擬的環(huán)境中進行的,事務提交時才將事務進行的所有修改更新到數(shù)據(jù)庫的存儲介質(zhì)上,如硬盤。在事務提交前,如果有操作失敗的情況,那么需要進行回滾操作,便可以取消事務所進行的修改,當事務被提交后,再執(zhí)行回滾是無效的。
         事務需要數(shù)據(jù)庫的支持,不是所有的數(shù)據(jù)庫都執(zhí)行事務,如MySQL中默認的數(shù)據(jù)庫都采用了MyISAM存儲引擎,它不支持事務,如果MySQL數(shù)據(jù)庫采用InnoDB存儲的引擎,便支持事務。通過DatabaseMetaData的supportsTransactions方法可以判斷數(shù)據(jù)庫是否支持事務。
         數(shù)據(jù)庫連接Connection對象默認是自動提交的,即在該連接下,每用Statement執(zhí)行一條SQL語句,便提交到數(shù)據(jù)庫。為了控制事務提交的時機,需要在事務開始前,調(diào)用Connection的setAutoCommit方法將數(shù)據(jù)庫連接的自動提交屬性關閉,此后,所有的操作都不會提交到數(shù)據(jù)庫,直到調(diào)用Connection的commit方法,提交事務位置。
         在提交事務之前,一旦有SQL語句執(zhí)行不通過,應調(diào)用Connection的rollback方法,執(zhí)行回滾操作,那么此前所有數(shù)據(jù)庫操作將無效。


    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.SQLException;
    import java.sql.Statement;

    /**
     * 判斷數(shù)據(jù)庫是否支持事務,如果支持,如何實現(xiàn)事務的提交與回滾。
     * MySQL中如果要使用事物,必須使用InnoDB存儲引擎,在創(chuàng)建表時,后面加上ENGINE=InnoDB。
     * MySQL默認的存儲引擎是MyISAM,不支持事物
     
    */

    public class Transaction {

        
    /**
         * 判斷數(shù)據(jù)庫是否支持事務
         * 
    @param con    數(shù)據(jù)庫的連接
         * 
    @return
         
    */

        
    public static boolean supportTransaction(Connection con){
            
    try {
                
    // 得到數(shù)據(jù)庫的元數(shù)據(jù)
                DatabaseMetaData md = con.getMetaData();
                
    return md.supportsTransactions();
            }
     catch (SQLException e) {
                e.printStackTrace();
            }

            
    return false;
        }

        
        
    /**
         * 將一組SQL語句放在一個事務里執(zhí)行,要某全部執(zhí)行通過,要某全部不執(zhí)行
         * 
    @param con    數(shù)據(jù)庫的連接
         * 
    @param sqls    待執(zhí)行的SQL數(shù)組
         
    */

        
    public static void goTransaction(Connection con, String[] sqls){
            
    if (sqls == null){
                
    return ;
            }

            Statement sm 
    = null;
            
    try {
                
    // 事務開始
                System.out.println("事務開始!");
                
    // 設置連接不自動提交,即用該連接進行的操作都不更新到數(shù)據(jù)庫
                con.setAutoCommit(false);
                sm 
    = con.createStatement();
                
    for (int i=0; i<sqls.length; i++){
                    
    // 執(zhí)行SQL語句,但是沒更新到數(shù)據(jù)庫
                    sm.execute(sqls[i]);
                }

                
    // 提交,立即更新到數(shù)據(jù)庫
                System.out.println("事務提交!");
                con.commit();
                System.out.println(
    "事務結束!");
                
    // 事務結束
            }
     catch (SQLException e) {
                
    try {
                    
    // 出現(xiàn)異常時,進行回滾,取消前面執(zhí)行的操作
                    System.out.println("事務執(zhí)行失敗,進行回滾!");
                    con.rollback();
                }
     catch (SQLException e1) {
                    e1.printStackTrace();
                }

            }
     finally {
                OperateDB.closeStatement(sm);
            }

        }

        
        
    public static void main(String[] args) throws ClassNotFoundException,
                SQLException 
    {
            String dbName 
    = "studentdb";
            String userName 
    = "test";
            String password 
    = "test";
            String[] sqls 
    = new String[3];
            sqls[
    0= "UPDATE student_basic_innodb SET score=93 where name='john'";
            sqls[
    1= "INSERT INTO student_basic_innodb (name, age, score)"
                
    + " VALUES ('zhangsan', 17, 86)";
            
    // 執(zhí)行這條語句會引起錯誤,因為表student_basic_innodb沒有xxxxxxx列
            sqls[2= "DELETE FROM student_basic_innodb where xxxxxxx='wade'";
            
            Connection con 
    = null;
            
    try {
                
    // 獲得數(shù)據(jù)庫連接
                con = DBConnector.getMySQLConnection(nullnullnull, dbName,
                        userName, password);
                
    // 判斷是否支持批處理
                boolean supportTransaction = Transaction.supportTransaction(con);
                System.out.println(
    "支持事務? " + supportTransaction);
                
    if (supportTransaction){
                    
    // 執(zhí)行事務
                    Transaction.goTransaction(con, sqls);
                }

            }
     catch (ClassNotFoundException e1) {
                
    throw e1;
            }
     catch (SQLException e2) {
                
    throw e2;
            }
     finally {
                
    // 關閉數(shù)據(jù)庫連接
                OperateDB.closeConnection(con);
            }

        }

    }


                                                                                                           --    學海無涯
            

    主站蜘蛛池模板: 啦啦啦高清视频在线观看免费| 亚洲成AV人在线观看网址| 亚洲欧好州第一的日产suv| 亚洲精品国产精品乱码不卡| 麻豆精品成人免费国产片| 最新亚洲精品国偷自产在线 | 最好看最新的中文字幕免费| 亚洲毛片无码专区亚洲乱| 四虎影视免费永久在线观看| 永久免费不卡在线观看黄网站| 亚洲人成小说网站色| 亚洲综合色自拍一区| 免费av欧美国产在钱| xxxxx做受大片在线观看免费| 亚洲高清资源在线观看| mm1313亚洲精品国产| 国产在线jyzzjyzz免费麻豆| 国产黄色片免费看| 亚洲日日做天天做日日谢| 国产精品亚洲A∨天堂不卡| 成人免费一区二区三区在线观看| 黄色网站软件app在线观看免费| 亚洲一线产区二线产区区| 亚洲A∨无码一区二区三区| 国产成人免费手机在线观看视频 | 亚洲天堂免费在线| 国产裸体美女永久免费无遮挡 | 两个人看的www高清免费视频 | 久久久受www免费人成| 亚洲精品无码人妻无码| 337p欧洲亚洲大胆艺术| 亚洲无线一二三四区手机| 日本特黄特黄刺激大片免费| 久视频精品免费观看99| 中文字幕免费在线看电影大全| 久久亚洲中文字幕无码| 亚洲不卡在线观看| 久久久久久亚洲AV无码专区| 中文字幕专区在线亚洲| 免费a级毛片网站| 在线视频免费国产成人|