激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 深入解析Java中的JDBC事務(wù)

深入解析Java中的JDBC事務(wù)

2020-01-02 14:17zinss26914 JAVA教程

這篇文章主要介紹了深入解析Java中的JDBC事務(wù),包含了Java多線程的事務(wù)并發(fā)等知識(shí),需要的朋友可以參考下

事務(wù)
事務(wù)是一步或多步組成操作序列組成的邏輯執(zhí)行單元,這個(gè)序列要么全部執(zhí)行,要么則全部放棄執(zhí)行。事務(wù)的四個(gè)特性:原子性(Atomicity)、一致性(Consistency)、隔離性(IsoIation)和持續(xù)性(Durability)原子性(Atomicity):事務(wù)應(yīng)用最小的執(zhí)行單元,不可再分。是事務(wù)中不可再分的最小邏輯執(zhí)行體。

一致性(Consistency):事務(wù)的執(zhí)行結(jié)果,必須使數(shù)據(jù)庫(kù)的從一個(gè)一致性的狀態(tài)變到另一個(gè)一致性的狀態(tài)。

隔離線(IsoIation):各個(gè)事務(wù)的執(zhí)行互不干擾,任意一個(gè)事務(wù)的內(nèi)部操作對(duì)其他并發(fā)的事務(wù),都是隔離的。也就是:并發(fā)執(zhí)行的事務(wù)之間不能看到對(duì)方的中間狀態(tài),并發(fā)執(zhí)行的事務(wù)之間不能互相影響。

持續(xù)性(Durability):持續(xù)性也稱為持久性(Persistence),指事務(wù)一旦提交,對(duì)數(shù)據(jù)所做的任何改變,都要記錄到永久存儲(chǔ)器中,通常就是保存在物理數(shù)據(jù)庫(kù)中。

通常數(shù)據(jù)庫(kù)的事務(wù)涉及到的語(yǔ)句有:一組DML(Data Munipulation Language,數(shù)據(jù)操作語(yǔ)言)語(yǔ)句,這組DML語(yǔ)句修改后數(shù)據(jù)將保持較好的一致性;    操作表的語(yǔ)句,如插入、修改、刪除等;一個(gè)DDL(Data Definition Language,數(shù)據(jù)定義語(yǔ)言)語(yǔ)句,操作數(shù)據(jù)對(duì)象的語(yǔ)言,有create、alter、drop。一個(gè)DCL(Data Control Language,數(shù)據(jù)控制語(yǔ)言)語(yǔ)句,主要有g(shù)rant、revoke語(yǔ)句。 DDL和DCL語(yǔ)句最多只能有一個(gè),因?yàn)樗鼈兌紩?huì)導(dǎo)致事務(wù)的立即提交。當(dāng)事務(wù)所包含的全部數(shù)據(jù)庫(kù)操作都成功執(zhí)行后,應(yīng)該提交事務(wù),使這些修改永久生效。事務(wù)提交有兩種方式:顯示提交和自動(dòng)提交。顯示提交:使用commit提交自動(dòng)提交:執(zhí)行DLL或DCL,或者程序正常退出 當(dāng)事務(wù)包含的任意一個(gè)數(shù)據(jù)庫(kù)操作執(zhí)行失敗后,應(yīng)該回滾(rollback)事務(wù),使該事務(wù)中所作的修改全部失效。事務(wù)的回滾方式有兩種:顯示回滾和自動(dòng)回滾。顯示回滾:使用rollback自動(dòng)回滾:系統(tǒng)錯(cuò)誤或強(qiáng)行退出。


事務(wù)并發(fā)處理可能的問題
1、臟讀(dirty read):一個(gè)事務(wù)讀取了另一個(gè)事務(wù)尚未提交的數(shù)據(jù)

2、不可重復(fù)讀(non-repeatable read):一個(gè)事務(wù)的操作導(dǎo)致另一個(gè)事務(wù)前后兩次讀到不同的數(shù)據(jù)

3、幻讀(phantom read):一個(gè)事務(wù)的操作導(dǎo)致另一個(gè)事務(wù)前后兩次查詢的結(jié)果數(shù)據(jù)量不同

舉例:

事務(wù)A、B并發(fā)執(zhí)行時(shí):

  •     當(dāng)A事務(wù)update后,B事務(wù)select讀取到A尚未提交的數(shù)據(jù),此時(shí)A事務(wù)rollback,則B讀到的數(shù)據(jù)是無(wú)效的臟數(shù)據(jù)
  •     當(dāng)B事務(wù)select讀取數(shù)據(jù)后,A事務(wù)update操作更改B事務(wù)select到的數(shù)據(jù),此時(shí)B事務(wù)再次讀取該數(shù)據(jù),發(fā)現(xiàn)前后兩次的數(shù)據(jù)不一樣
  •     當(dāng)B事務(wù)select讀取數(shù)據(jù)后,A事務(wù)insert或delete了一條滿足A事務(wù)的select條件的記錄,此時(shí)B事務(wù)再次select,發(fā)現(xiàn)查詢到前次不存在的記錄,或者前次的某個(gè)記錄不見了

 

Java JDBC事務(wù)機(jī)制
  

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
  
  
 public class JDBCTransaction {
   public static final String URL = "com.mysql.jdbc.Driver";
   public static final String USER = "root";
   public static final String PASSWD = "123456";
  
   public static void jdbcTransaction(int id) {
     Connection conn = null;
     PreparedStatement pstmtupdate = null;
     PreparedStatement pstmtquery = null;
     String updatesql = "更新sql";
     String querysql = "查詢sql";
  
     try {
       Class.forName("com.mysql.jdbc.Driver");
       conn = DriverManager.getConnection(URL, USER, PASSWD);
  
       conn.setAutoCommit(false); // 自動(dòng)提交設(shè)置為false
  
       // 執(zhí)行更新操作
       pstmtupdate = conn.prepareStatement(updatesql);
       pstmtupdate.executeUpdate();
  
       // 執(zhí)行查找操作
       pstmtquery = conn.prepareStatement(querysql);
       pstmtquery.executeQuery();
  
       conn.commit();
       conn.setAutoCommit(true);
  
       pstmtupdate.close();
       pstmtquery.close();
       conn.close();
     } catch (Exception e) {
       try {
         conn.rollback();
       } catch (SQLException e1) {}
       e.printStackTrace();
     } finally {
       try {
         if (pstmtupdate != null) {
           pstmtupdate.close();
         }
  
         if (pstmtquery != null) {
           pstmtquery.close();
         }
  
         if (conn != null) {
           conn.close();
         }
       } catch (SQLException e2) {}
     }
   }
 }


JDBC的事務(wù)支持

JDBC的Connection也支持事物,Connection默認(rèn)打開自動(dòng)提交,即關(guān)閉事物。也就是說(shuō),每條SQL語(yǔ)句執(zhí)行就會(huì)立即提交到數(shù)據(jù)庫(kù),永久生效,無(wú)法對(duì)其進(jìn)行操作。關(guān)閉Connection的自動(dòng)提交,開啟事物。Connection的setAutoCommit方法即可:connection.setAutoCommit(false);通過connection.getAutoCommit()來(lái)獲取事物的模式。當(dāng)我們開啟事物后,在當(dāng)前Connection中完成的數(shù)據(jù)庫(kù)操作,都不會(huì)立即提交到數(shù)據(jù)庫(kù),需要調(diào)用Connection的commit方法才行。如果有語(yǔ)句執(zhí)行失敗,可以調(diào)用rollback來(lái)回滾。注意:如果Connection遇到未處理的SQLException異常時(shí),系統(tǒng)將非正常退出,系統(tǒng)會(huì)自動(dòng)回滾該事務(wù)。如果程序捕捉了該異常,則需要在異常處理中顯示回滾事務(wù)。 Connection提供了設(shè)置事務(wù)中間保存點(diǎn)的方法:setSavepoint,有2個(gè)方法可以設(shè)置中間點(diǎn):Savepoint setSavepoint():在當(dāng)前事務(wù)中創(chuàng)建一個(gè)未命名的中間點(diǎn),并返回該中間點(diǎn)的Savepoint對(duì)象。Savepoint setSavepoint(String name):當(dāng)前事務(wù)中創(chuàng)建一個(gè)具有指定名稱的中間點(diǎn),并返回該中間點(diǎn)的Savepoint對(duì)象通常setSavepoint(String name)設(shè)置中間點(diǎn)的名稱,事務(wù)回滾并不是通過中間點(diǎn)的名稱進(jìn)行回滾的,而是根據(jù)中間點(diǎn)對(duì)象進(jìn)行回滾的。設(shè)置名稱只是更好的區(qū)分中間點(diǎn)對(duì)象,用Connection的rollback(Savepoint savepoint)方法即可完成回滾到指定中間點(diǎn)。

JDBC對(duì)事務(wù)的支持體現(xiàn)在三個(gè)方面:

1、自動(dòng)提交模式(auto-commit mode)

Connection提供了一個(gè)auto-commit屬性來(lái)指定事務(wù)何時(shí)結(jié)束

2、當(dāng)auto-commit為true時(shí),當(dāng)每個(gè)獨(dú)立SQL操作的執(zhí)行完畢,事務(wù)立即自動(dòng)提交,也就是說(shuō)每個(gè)SQL操作都是一個(gè)事務(wù)

一個(gè)獨(dú)立SQL操作什么時(shí)候算執(zhí)行完畢,JDBC規(guī)范是這樣定義的:

對(duì)數(shù)據(jù)操作語(yǔ)言(DML)和數(shù)據(jù)定義語(yǔ)言(DDL),語(yǔ)句一執(zhí)行完就視為執(zhí)行完畢

3、當(dāng)auto-commit為false時(shí),每個(gè)事務(wù)都必須顯示調(diào)用commit方法進(jìn)行提交,或者顯示調(diào)用rollback方法進(jìn)行回滾。auto-commit默認(rèn)為true

事務(wù)隔離級(jí)別(Transaction Isolation Levels)
JDBC定義了五種事務(wù)隔離級(jí)別:

  •     TRANSACTION_NONE JDBC驅(qū)動(dòng)不支持事務(wù)
  •     TRANSACTION_READ_UNCOMMITTED 允許臟讀、不可重復(fù)讀和幻讀
  •     TRANSACTION_READ_COMMITTED 禁止臟讀,但允許不可重復(fù)讀和幻讀
  •     TRANSACTION_REPEATABLE_READ 禁止臟讀和不可重復(fù)讀,單運(yùn)行幻讀
  •     TRANSACTION_SERIALIZABLE 禁止臟讀、不可重復(fù)讀和幻讀


保存點(diǎn)
JDBC定義了SavePoint接口,提供一個(gè)更細(xì)粒度的事務(wù)控制機(jī)制。當(dāng)設(shè)置了一個(gè)保存點(diǎn)后,可以rollback到該保存點(diǎn)處的狀態(tài),而不是rollback整個(gè)事務(wù)
首先,我們來(lái)看看現(xiàn)有的JDBC操作會(huì)給我們帶來(lái)什么重大問題,比如有一個(gè)業(yè)務(wù):當(dāng)我們修改一個(gè)信息后再去查詢這個(gè)信息,看似是一個(gè)簡(jiǎn)單的業(yè)務(wù),實(shí)現(xiàn)起來(lái)也非常容易,但當(dāng)這個(gè)業(yè)務(wù)放在多線程高并發(fā)的平臺(tái)下,問題自然就出現(xiàn)了,比如當(dāng)我們執(zhí)行了一個(gè)修改后,在執(zhí)行查詢前有一個(gè)線程也執(zhí)行了修改語(yǔ)句,這時(shí)我們?cè)賵?zhí)行查詢,看到的信息就有可能與我們修改的不同。為了解決這一問題,我們必須引入JDBC事務(wù)機(jī)制,其實(shí)現(xiàn)代碼很簡(jiǎn)單,給出示例代碼供大家參考:

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 少妇一级淫片免费看 | 精品久久一区二区 | 国产色爱综合网 | 欧美日韩国产一区二区三区在线观看 | 欧美人的天堂一区二区三区 | 黄色片网站在线免费观看 | 精品亚洲一区二区 | 国产无遮挡成人免费视频 | 羞羞色在线观看 | 亚洲国产中文字幕 | 欧美精品欧美 | 国产日本在线播放 | 免费看成人毛片 | 欧美一级黄色网 | 毛片免费观看视频 | 久久精品国产99国产精品澳门 | 成人不卡一区二区 | 日本成年网 | 色婷婷久久久亚洲一区二区三区 | 国产黄色一级大片 | 中文字幕国 | 亚洲一区二区三区精品在线观看 | 亚洲欧美一区二区三区在线观看 | 一区二区三视频 | 国产乱色精品成人免费视频 | 国产噜噜噜噜久久久久久久久 | 久久色网站 | 国产妞干网 | 二级大黄大片高清在线视频 | japanesexxxxxxxhd | 久久精品日产高清版的功能介绍 | 亚洲免费毛片基地 | 色妞欧美 | 色678黄网站全部免费 | 亚洲午夜不卡 | 国产高潮国产高潮久久久91 | 中国毛片在线观看 | 午夜精品久久久久久久99热浪潮 | 国产精品国产成人国产三级 | 久久蜜桃香蕉精品一区二区三区 | 97精品视频在线观看 |