1. package book.database;  
  2.  
  3. import java.sql.Connection;  
  4. import java.sql.DatabaseMetaData;  
  5. import java.sql.SQLException;  
  6. import java.sql.Statement;  
  7.  
  8. /**  
  9.  * 判断数据库是否支持事务,如果支持,如何实现事务的提交与回滚。  
  10.  * MySQL中如果要使用事物,必须使用InnoDB存储引擎,在创建表时,后面加上ENGINE=InnoDB。  
  11.  * MySQL默认的存储引擎是MyISAM,不支持事物  
  12.  */ 
  13. public class Transaction {  
  14.  
  15.     /**  
  16.      * 判断数据库是否支持事务  
  17.      * @param con   数据库的连接  
  18.      * @return  
  19.      */ 
  20.     public static boolean supportTransaction(Connection con){  
  21.         try {  
  22.             // 得到数据库的元数据  
  23.             DatabaseMetaData md = con.getMetaData();  
  24.             return md.supportsTransactions();  
  25.         } catch (SQLException e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.         return false;  
  29.     }  
  30.       
  31.     /**  
  32.      * 将一组SQL语句放在一个事务里执行,要某全部执行通过,要某全部不执行  
  33.      * @param con   数据库的连接  
  34.      * @param sqls  待执行的SQL数组  
  35.      */ 
  36.     public static void goTransaction(Connection con, String[] sqls){  
  37.         if (sqls == null){  
  38.             return ;  
  39.         }  
  40.         Statement sm = null;  
  41.         try {  
  42.             // 事务开始  
  43.             System.out.println("事务开始!");  
  44.             // 设置连接不自动提交,即用该连接进行的操作都不更新到数据库  
  45.             con.setAutoCommit(false);  
  46.             sm = con.createStatement();  
  47.             for (int i=0; i<sqls.length; i++){  
  48.                 // 执行SQL语句,但是没更新到数据库  
  49.                 sm.execute(sqls[i]);  
  50.             }  
  51.             // 提交,立即更新到数据库  
  52.             System.out.println("事务提交!");  
  53.             con.commit();  
  54.             System.out.println("事务结束!");  
  55.             // 事务结束  
  56.         } catch (SQLException e) {  
  57.             try {  
  58.                 // 出现异常时,进行回滚,取消前面执行的操作  
  59.                 System.out.println("事务执行失败,进行回滚!");  
  60.                 con.rollback();  
  61.             } catch (SQLException e1) {  
  62.                 e1.printStackTrace();  
  63.             }  
  64.         } finally {  
  65.             OperateDB.closeStatement(sm);  
  66.         }  
  67.     }  
  68.       
  69.     public static void main(String[] args) throws ClassNotFoundException,  
  70.             SQLException {  
  71.         String dbName = "studentdb";  
  72.         String userName = "test";  
  73.         String password = "test";  
  74.         String[] sqls = new String[3];  
  75.         sqls[0] = "UPDATE student_basic_innodb SET score=93 where name='john'";  
  76.         sqls[1] = "INSERT INTO student_basic_innodb (name, age, score)" 
  77.             + " VALUES ('zhangsan', 17, 86)";  
  78.         // 执行这条语句会引起错误,因为表student_basic_innodb没有xxxxxxx列  
  79.         sqls[2] = "DELETE FROM student_basic_innodb where xxxxxxx='wade'";  
  80.           
  81.         Connection con = null;  
  82.         try {  
  83.             // 获得数据库连接  
  84.             con = DBConnector.getMySQLConnection(nullnullnull, dbName,  
  85.                     userName, password);  
  86.             // 判断是否支持批处理  
  87.             boolean supportTransaction = Transaction.supportTransaction(con);  
  88.             System.out.println("支持事务? " + supportTransaction);  
  89.             if (supportTransaction){  
  90.                 // 执行事务  
  91.                 Transaction.goTransaction(con, sqls);  
  92.             }  
  93.         } catch (ClassNotFoundException e1) {  
  94.             throw e1;  
  95.         } catch (SQLException e2) {  
  96.             throw e2;  
  97.         } finally {  
  98.             // 关闭数据库连接  
  99.             OperateDB.closeConnection(con);  
  100.         }  
  101.     }