前言
本博主將用CSDN記錄軟件開發(fā)求學(xué)之路上親身所得與所學(xué)的心得與知識,有興趣的小伙伴可以關(guān)注博主!也許一個人獨行,可以走的很快,但是一群人結(jié)伴而行,才能走的更遠!
一、數(shù)據(jù)庫事務(wù)介紹
-
事務(wù):一組邏輯操作單元,使數(shù)據(jù)從一種狀態(tài)變換到另一種狀態(tài)。
-
事務(wù)處理(事務(wù)操作):保證所有事務(wù)都作為一個工作單元來執(zhí)行,即使出現(xiàn)了故障,都不能改變這種執(zhí)行方式。當在一個事務(wù)中執(zhí)行多個操作時,要么所有的事務(wù)都被提交(commit),那么這些修改就永久地保存下來;要么數(shù)據(jù)庫管理系統(tǒng)將放棄所作的所有修改,整個事務(wù)**回滾(rollback)**到最初狀態(tài)。
-
為確保數(shù)據(jù)庫中數(shù)據(jù)的一致性,數(shù)據(jù)的操縱應(yīng)當是離散的成組的邏輯單元:當它全部完成時,數(shù)據(jù)的一致性可以保持,而當這個單元中的一部分操作失敗,整個事務(wù)應(yīng)全部視為錯誤,所有從起始點以后的操作應(yīng)全部回退到開始狀態(tài)。
二、JDBC事務(wù)處理
-
數(shù)據(jù)一旦提交,就不可回滾。
-
數(shù)據(jù)什么時候意味著提交?
- 當一個連接對象被創(chuàng)建時,默認情況下是自動提交事務(wù):每次執(zhí)行一個 SQL 語句時,如果執(zhí)行成功,就會向數(shù)據(jù)庫自動提交,而不能回滾。
- **關(guān)閉數(shù)據(jù)庫連接,數(shù)據(jù)就會自動的提交。**如果多個操作,每個操作使用的是自己單獨的連接,則無法保證事務(wù)。即同一個事務(wù)的多個操作必須在同一個連接下。
-
JDBC程序中為了讓多個 SQL 語句作為一個事務(wù)執(zhí)行:
- 調(diào)用 Connection 對象的 setAutoCommit(false); 以取消自動提交事務(wù)
- 在所有的 SQL 語句都成功執(zhí)行后,調(diào)用 commit(); 方法提交事務(wù)
- 在出現(xiàn)異常時,調(diào)用 rollback(); 方法回滾事務(wù)
若此時 Connection 沒有被關(guān)閉,還可能被重復(fù)使用,則需要恢復(fù)其自動提交狀態(tài) setAutoCommit(true)。尤其是在使用數(shù)據(jù)庫連接池技術(shù)時,執(zhí)行close()方法前,建議恢復(fù)自動提交狀態(tài)。
【案例:用戶AA向用戶BB轉(zhuǎn)賬100】
public void testJDBCTransaction() {
Connection conn = null;
try {
// 1.獲取數(shù)據(jù)庫連接
conn = JDBCUtils.getConnection();
// 2.開啟事務(wù)
conn.setAutoCommit(false);
// 3.進行數(shù)據(jù)庫操作
String sql1 = "update user_table set balance = balance - 100 where user = ?";
update(conn, sql1, "AA");
// 模擬網(wǎng)絡(luò)異常
//System.out.println(10 / 0);
String sql2 = "update user_table set balance = balance + 100 where user = ?";
update(conn, sql2, "BB");
// 4.若沒有異常,則提交事務(wù)
conn.commit();
} catch (Exception e) {
e.printStackTrace();
// 5.若有異常,則回滾事務(wù)
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
//6.恢復(fù)每次DML操作的自動提交功能
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
//7.關(guān)閉連接
JDBCUtils.closeResource(conn, null, null);
}
}
其中,對數(shù)據(jù)庫操作的方法為:
//使用事務(wù)以后的通用的增刪改操作(version 2.0)
public void update(Connection conn ,String sql, Object... args) {
PreparedStatement ps = null;
try {
// 1.獲取PreparedStatement的實例 (或:預(yù)編譯sql語句)
ps = conn.prepareStatement(sql);
// 2.填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
// 3.執(zhí)行sql語句
ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 4.關(guān)閉資源
JDBCUtils.closeResource(null, ps);
}
}
三、事務(wù)的ACID屬性
-
原子性(Atomicity)
原子性是指事務(wù)是一個不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。 -
一致性(Consistency)
事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)變換到另外一個一致性狀態(tài)。 -
隔離性(Isolation)
事務(wù)的隔離性是指一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾。 -
持久性(Durability)
持久性是指一個事務(wù)一旦被提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,接下來的其他操作和數(shù)據(jù)庫故障不應(yīng)該對其有任何影響。
1、數(shù)據(jù)庫的并發(fā)問題
-
對于同時運行的多個事務(wù), 當這些事務(wù)訪問數(shù)據(jù)庫中相同的數(shù)據(jù)時, 如果沒有采取必要的隔離機制, 就會導(dǎo)致各種并發(fā)問題:
- 臟讀: 對于兩個事務(wù) T1, T2, T1 讀取了已經(jīng)被 T2 更新但還沒有被提交的字段。之后, 若 T2 回滾, T1讀取的內(nèi)容就是臨時且無效的。
- 不可重復(fù)讀: 對于兩個事務(wù)T1, T2, T1 讀取了一個字段, 然后 T2 更新了該字段。之后, T1再次讀取同一個字段, 值就不同了。
- 幻讀: 對于兩個事務(wù)T1, T2, T1 從一個表中讀取了一個字段, 然后 T2 在該表中插入了一些新的行。之后, 如果 T1 再次讀取同一個表, 就會多出幾行。
-
數(shù)據(jù)庫事務(wù)的隔離性: 數(shù)據(jù)庫系統(tǒng)必須具有隔離并發(fā)運行各個事務(wù)的能力, 使它們不會相互影響, 避免各種并發(fā)問題。
-
一個事務(wù)與其他事務(wù)隔離的程度稱為隔離級別。數(shù)據(jù)庫規(guī)定了多種事務(wù)隔離級別, 不同隔離級別對應(yīng)不同的干擾程度, 隔離級別越高, 數(shù)據(jù)一致性就越好, 但并發(fā)性越弱。
2、四種隔離級別
- 數(shù)據(jù)庫提供的4種事務(wù)隔離級別:
-
Oracle 支持的 2 種事務(wù)隔離級別:READ COMMITED, SERIALIZABLE。 Oracle 默認的事務(wù)隔離級別為: READ COMMITED 。
-
Mysql 支持 4 種事務(wù)隔離級別。Mysql 默認的事務(wù)隔離級別為: REPEATABLE READ。
3、在MySql中設(shè)置隔離級別
-
每啟動一個 mysql 程序, 就會獲得一個單獨的數(shù)據(jù)庫連接. 每個數(shù)據(jù)庫連接都有一個全局變量 @@tx_isolation, 表示當前的事務(wù)隔離級別。
-
查看當前的隔離級別:
SELECT @@tx_isolation;
-
設(shè)置當前 mySQL 連接的隔離級別:
set transaction isolation level read committed;
-
設(shè)置數(shù)據(jù)庫系統(tǒng)的全局的隔離級別:
set global transaction isolation level read committed;
-
補充操作:
-
創(chuàng)建mysql數(shù)據(jù)庫用戶:文章來源:http://www.zghlxwxcb.cn/news/detail-442678.html
create user tom identified by 'abc123';
-
授予權(quán)限文章來源地址http://www.zghlxwxcb.cn/news/detail-442678.html
#授予通過網(wǎng)絡(luò)方式登錄的tom用戶,對所有庫所有表的全部權(quán)限,密碼設(shè)為abc123. grant all privileges on *.* to tom@'%' identified by 'abc123'; #給tom用戶使用本地命令行方式,授予atguigudb這個庫下的所有表的插刪改查的權(quán)限。 grant select,insert,delete,update on atguigudb.* to tom@localhost identified by 'abc123';
-
到了這里,關(guān)于JDBC詳解(六):數(shù)據(jù)庫事務(wù)(超詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!