TPL:事務控制語句
start transaction:開啟一次事務
rollback:回滾
commit:提交事務
JDBC中與事務有關的方法:
Connection.setAutoCommit(boolean b)
Connection.rollback()
Connection.rollback(Savepoint sp)
Connection.commit();
*****四、事務的特性(隔離級別)
A:原子性。說明事務是一個不可分割的單位。
C:一致性.事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態.(比如轉賬)
*I:隔離性。一個事務不能被其他事務打擾。
D:持久性。事務一旦提交,就應該被永久保存起來。
如果不考慮事務的隔離級別,會出現以下“不正確”的情況:
臟讀:指一個事務讀到了另一個事務中未提交的數據。
不可重復讀:針對一條記錄的,同一條記錄前后不一樣
虛讀(幻讀):針對一張表,前后讀到的記錄條數不一樣。
MySQL中控制事務隔離級別的語句:
select @@tx_isolation; //查看當前的事務隔離級別
set transaction isolation level 你的級別(四種之一);//設置隔離級別
隔離級別的分類:
READ UNCOMMITTED(未授權讀):臟讀、不可重復讀、虛讀都有可能發生。
READ COMMITTED(授權讀):能避免臟讀,不可重復讀、虛讀都有可能發生。
REPEATABLE READ(可重復讀):能避免臟讀、不可重復度,虛讀都有可能發生。
SERIALIZABLE(序列化):能避免臟讀、不可重復度、虛讀。
oracle隔離級別 只有READ COMMITTED和 SERIALIZABLE
因為當有人對數據庫的數據進行任何寫操作(DML操作)時,Oracle數據庫系統首先將原始的數據復制到回滾段中,之后才做相應的操作,在事務處理結束之前其他的用戶可以讀這些數據,但是讀到的都是回滾段上的數據。

1 create table bank 2 { 3 id int primary key, 4 name varchar(10), 5 money int 6 }
搭建數據庫連接
c3p0-config.xml下

1 <?xml version="1.0" encoding="UTF-8"?> 2 <c3p0-config> 3 <default-config> 4 <property name="driverClass">com.mysql.jdbc.Driver</property> 5 <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/bank</property> 6 <property name="user">root</property> 7 <property name="password">mima</property> 8 </default-config> 9 </c3p0-config>
JdbcUtil.java 導入相關的類

1 public class JdbcUtil { 2 private static ComboPooledDataSource dataSource =new ComboPooledDataSource(); 3 public static ComboPooledDataSource getDataSource() 4 { 5 return dataSource; 6 } 7 }
測試代碼 。 注意 事務是針對一次連接Connection的,如果
QueryRunner runner =new QueryRunner(ds); 的話可能對於連接 會有不同的Connecton就達不到效果了
1 public static void main(String[] args) throws Exception { 2 DataSource ds=JdbcUtil.getDataSource(); 3 Connection con=ds.getConnection(); 4 QueryRunner runner =new QueryRunner(); 5 try { 6 con.setAutoCommit(false); 7 } catch (SQLException e1) { 8 e1.printStackTrace(); 9 } 10 try { 11 String sql1="update money_table set money=money+1000 where name = ?"; 12 runner.update(con,sql1, new Object[]{"aa"}); 13 int i=1/0; 14 String sql2="update money_table set money=money-1000 where name = ?"; 15 runner.update(con,sql2, new Object[]{"bb"}); 16 con.commit(); 17 18 } catch (Exception e) { 19 try { 20 con.rollback(); 21 } catch (SQLException e1) { 22 e1.printStackTrace(); 23 } 24 e.printStackTrace(); 25 } 26 finally 27 { 28 29 } 30 31 }
數據正常。
1 public static void main(String[] args) throws Exception { 2 DataSource ds=JdbcUtil.getDataSource(); 3 Connection con=ds.getConnection(); 4 QueryRunner runner =new QueryRunner(); 5 try { 6 con.setAutoCommit(false); 7 } catch (SQLException e1) { 8 e1.printStackTrace(); 9 } 10 Savepoint sp=null; 11 try { 12 String sql1="update money_table set money=money+1000 where name = ?"; 13 runner.update(con,sql1, new Object[]{"aa"}); 14 String sql2="update money_table set money=money-1000 where name = ?"; 15 runner.update(con,sql2, new Object[]{"bb"}); 16 sp=con.setSavepoint(); 17 int i=1/0; 18 String sql3="update money_table set money=money+1000 where name = ?"; 19 runner.update(con,sql3, new Object[]{"cc"}); 20 String sql4="update money_table set money=money-1000 where name = ?"; 21 runner.update(con,sql4, new Object[]{"dd"}); 22 23 24 } catch (Exception e) { 25 try { 26 con.rollback(sp); 27 } catch (SQLException e1) { 28 e1.printStackTrace(); 29 } 30 e.printStackTrace(); 31 } 32 finally 33 { 34 con.commit(); 35 } 36 37 }