一、事務概述
1.什麼是事務
一件事情有n個組成單元 要不這n個組成單元同時成功 要不n個單元就同時失敗
就是將n個組成單元放到一個事務中
2.mysql的事務
默認的事務:一條sql語句就是一個事務 默認就開啓事務並提交事務
手動事務:
1)顯示的開啓一個事務:start transaction
2)事務提交:commit代表從開啓事務到事務提交 中間的所有的sql都認爲有效真正的更新數據庫
3)事務的回滾:rollback 代表事務的回滾 從開啓事務到事務回滾 中間的所有的sql操作都認爲無效數據庫沒有被更新
二、JDBC事務操作
默認是自動事務:
執行sql語句:executeUpdate() ---- 每執行一次executeUpdate方法代表事務自動提交
通過jdbc的API手動事務:
開啓事務:conn.setAutoComnmit(false);
提交事務:conn.commit();
回滾事務:conn.rollback();
注意:控制事務的connnection必須是同一個
執行sql的connection與開啓事務的connnection必須是同一個才能對事務進行控制
三、DBUtils事務操作
1.QueryRunner
有參構造:QueryRunner runner = new QueryRunner(DataSource dataSource)
;
有參構造將數據源(連接池)作爲參數傳入QueryRunner,QueryRunner會從連接池中獲得一個數據庫連接資源操作數據庫,所以直接使用無Connection參數的update方法即可操作數據庫,即runner.update(sql)
int update(String sql); //sql=要執行的sql語句
int update(Connection conn, String sql); //conn=使用的connection連接,sql=要執行的sql語句
無參構造:QueryRunner runner = new QueryRunner();
無參的構造沒有將數據源(連接池)作爲參數傳入QueryRunner,那麼我們在使用QueryRunner對象操作數據庫時要使用有Connection參數的方法
2.因爲使用事務,如果開啓事務期間,同時有多個connection連接,則不能實現事務,因此如果使用DBUtils工具類,使用QueryRunner的有參構造的話,表示隨機從連接池中選取,這樣的話事務不能實現,所以必須使用QueryRunner的無參構造方法,然後創建一個Connection對象來使用。
Connection conn = null;
try {
QueryRunner runner = new QueryRunner();
//runner.update("update account set money=15000 where name='tom'");
//獲得一個Connection
conn = DataSourceUtils.getConnection();
//開啓事務
conn.setAutoCommit(false);
runner.update(conn, "update account set money=15000 where name='tom'");
//提交或回滾事務
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}