接著JDBC的進化3,我們來講數據庫事務。
事務:1組邏輯操作單元,使數據從1種狀態變換到另外一種狀態。
怎樣理解呢?
1組邏輯單元:我認為指的是多條的DML操作,只是1條DML語句的話,對mysql來講,履行完成功就自動提交了,沒成功的話,就沒成功嘍,這樣說來,1條DML語句就相當于1個原子,不可再分了。
從1種狀態變換到另外一種狀態:即這組操作是成功了還是失敗了,他們必須同時都成功,有1個失敗,就退回到出發點。例如銀行的轉賬,不能1個成功,1個失敗吧。
來看看JDBC的事務處理:
先來看看,在甚么時候,事務處理睬開始,甚么時候結束,針對確當然是我們的程序!
事務處理的開始:
以第1個DML語句履行為開始
事務處理的結束:
1.提交或回滾
2.正常結束
3.程序異常
來1個正確的例子:
@Test
public void test() {
String sql1 = "UPDATE user_table SET balance = balance - 100 WHERE `user` = ?";
String sql2 = "UPDATE user_table SET balance = balance + 100 WHERE `user` = ?";
Object[] obj1 = new Object[1];
obj1[0] = new String("AA");
Object[] obj2 = new Object[1];
obj2[0] = new String("BB");
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
conn.setAutoCommit(false);
prepareUpdate(conn, sql1, obj1);
prepareUpdate(conn, sql2, obj2);
conn.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(null, null, conn);
}
}
public int prepareUpdate(Connection conn, String sql, Object... args) {
// get preparedStatement's object
PreparedStatement ps = null;
// execute the ps
int rows = 0;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rows = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(ps, null);
}
// return
return rows;
}
這就是1個正確的事務處理,保證了兩個更新都成功,不會由于斷開連接或是異常的出現而使數據更新出錯。
要測試的話,在兩個update中間加上異常就能夠了。需要注意的是,不能自定義異常,假設自定義異常,下面的代碼就永久運行不到,回報編譯毛病。(自定義異常相當于return語句)
補充1點:
事務的ACID(acid)屬性
1.原子性
2.1致性
3.隔離性
4.持久性
事務的隔離級別:
產生的問題:
1.臟讀
2.不可重復讀
3.幻讀
隔離級別:
Oracle 支持的 2 種事務隔離級別:READ COMMITED, SERIALIZABLE。 Oracle 默許的事務隔離級別為: READ COMMITED
Mysql 支持 4 種事務隔離級別. Mysql 默許的事務隔離級別為: REPEATABLE READ
查看和設置事務級別:
查看當前的隔離級別: SELECT @@tx_isolation;
設置當前 mySQL 連接的隔離級別:
set transaction isolation level read committed;
設置數據庫系統的全局的隔離級別:
set global transaction isolation level read committed;
好了,over。
上一篇 PHP正則表達式的匹配
下一篇 Linux man系統使用基礎