日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

什么叫事务?Java如何处理事务呢?

發(fā)布時間:2025/3/17 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 什么叫事务?Java如何处理事务呢? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么叫事務?這些就是數據庫特有的術語了。懶蟲在這里口頭解釋:就是把多件事情當做一件事情來處理。也就是大家同在一條船上,要活一起活,要over一起over !

   我為什么要使用事務? 俺這里再舉個很俗很俗的例子:

     俺到銀行存錢,于是有這么幾個步驟:
       1、把錢交給工作人員;2、工作人員填單;3、將單子給我簽字;4、工作人員確認并輸入電腦。

   要是,要是我把錢交給工作人員之后,進行到3我簽字了。那哥們突然心臟病發(fā)作,over掉了,那,我的錢還沒有輸入電腦,但我卻交了錢又簽字確認了,而并沒有其他任何記錄。我豈不是要虧死了???我的血汗錢啊!趕緊退給我!!

   于是,在數據庫里產生了這么一個術語:事務(Transaction),也就是要么成功,要么失敗,并恢復原狀。
  
   還是寫程序把:

   Create Proc sp我去存款(@M Money , @iOperator Int)
   As
   Begin
    Declare @i int

    Begin Tran           --激活事務
     Exec @i=sp交錢 @m,@iOperator
     if @i<>0           --這里一般用系統錯誤號 @@Error。我這里為了舉例子沒有用到。需要根據實際情況。
     begin
      Rollback Tran                   --回滾事務
      RaisError ('銀行的窗口太少了,我懶得排隊,不交了!:( ', 16, 1) with Log --記錄日志
      Return -1                     --返回錯誤號
     end

     Exec @i=sp填單 @m,@iOperator
     if @i<>0
     begin
      Rollback Tran                   --回滾事務
      RaisError ('銀行的哥們打印機出了點毛病,打印不出單子來,把錢退回來給我吧??', 16, 1) with Log
      Return -2                     
     end

     Exec @i=sp簽字 @m
     if @i<>0
     begin
      Rollback Tran                   --回滾事務
      RaisError ('我靠?什么爛銀行,換了3支筆都寫不出水來!!老子不存了!!不簽!', 16, 1) with Log 
      Return -3                     
     end

     Exec @i=sp輸入電腦 @m,@iOperator
     if @i<>0
     begin
      Rollback Tran                   --回滾事務
      RaisError ('什么意思?磁盤空間已滿?好了好了,把錢給我,我到旁邊的這家銀行!', 16, 1) with Log 
      Return -4                     
     end
 
    Commit Tran        --提交事務
    Return 0
  End
 

       ----------------------------------------------------------------------
       以上是偽代碼,模擬我去存款的過程。

Java如何處理事務呢? 簡單事務的概念


  例如我們有一個訂單庫存管理系統,每一次生成訂單的同時我們都要消減庫存。通常來說訂單和庫存在數據庫里是分兩張表來保存的:訂單表,庫存表。每一次我們追加一個訂單實際上需要兩步操作:在訂單表中插入一條數據,同時修改庫存的數據。

  這樣問題來了,例如我們需要一個單位為10的訂單,庫存中有30件,理想的操作是我們在訂單表中插入了一條單位為10的訂單,之后將庫存表中的數據修改為20。但是有些時候事情并不是總是按照你的想法發(fā)生,例如:在你修改庫存的時候,數據庫突然由于莫名其妙的原因無法連接上了。也就是說庫存更新失敗了。但是訂單已經產生了,那么怎么辦呢?沒辦法,只有手動的修改。所以最好的方式是將訂單插入的操作和庫存修改的操作綁定在一起,必須同時成功或者什么都不做。這就是事務。

  Java如何處理事務呢?

  我們從java.sql.Connection說起,Connection表示了一個和數據庫的鏈接,可以通過Connection來對數據庫操作。在通常情況是Connection的屬性是自動提交的,也就是說每次的操作真的更新了數據庫,真的無法回退了。針對上述的例子,一旦庫存更新失敗了,訂單無法回退,因為訂單真的插入到了數據庫中。這并不是我們希望的。

  我們希望的是:看起來成功了,但是沒有真的操作數據庫,知道我想讓他真的發(fā)生。可以通過Connection的setAutoCommit(false)讓Connection不自動提交你的數據,除非你真的想提交。那么如何讓操作真的發(fā)生呢?可以使用Connection的commit方法。如何讓操作回退呢?使用rollback方法。

  例如:

  try{

  Connection conn = getConnection(); // 不管如何我們得到了鏈接

  conn.setAutoCommit(false);

  // 插入訂單

  // 修改庫存

  conn.commit(); // 成功的情況下,提交更新。

  } catch(SQLException ex) {

  conn.rollback(); // 失敗的情況下,回滾所有的操作

  } finally {

  conn.close();

  }

  這里有一點非常重要,事務是基于數據庫鏈接的。所以在但數據庫的情況下,事務操作很簡單。

  那么如果表分布在兩個不同的數據庫中呢?

  例如訂單表在訂單庫中,庫存表在庫存庫中,那么我們如何處理這樣的事務呢?

  需要注意,提交也可以遇到錯誤呀!

  try{

  Connection conn1 = getConnection1();

  Connection conn2 = getConnection2();

  // 基于conn1做插入操作

  // 基于conn2做更新操作

  try{

  conn1.commit()

  } catch(SQLExcetion ) {

  conn1.rollback();

  }

  try {

  conn2.commit();

  } catch(SQLException ) {

  conn2.rollbakc();

  // 保證肯定刪除剛才插入的訂單。

  }

  } catch(SQLException ex) {

  // 如果插入失敗,conn1.rollback

  // 如果更新失敗,conn1.rollback && conn2.rollback

  } finally {

  conn1.close();

  conn2.close();

  }

  看看上述的代碼就知道,其實操作非常的復雜,甚至:保證肯定刪除剛才插入的訂單根本無法保證。

  在上述情況下的事務可以稱之為分布式事務,通過上述的代碼中事務同時提交處理的部分我們可以得出,要想處理分布式事務,必須有獨立于數據庫的第三方的事務處理組件。

  幸運的是通常情況下,JavaEE兼容的應用服務器,例如:Weblogic,Websphere,JBoss,Glassfish等都有這種分布式事務處理的組件。

  如何使用應用服務器的分布式事務管理器處理分布式事務?

  以galssfish為例

  1 建立對應兩個數據庫的XA(javax.sql.XADataSource)類型的數據源。

  2 使用UserTransaction來保證分布式事務。

  try{

  Connection conn1 = datasource1.getConnection();

  Connection conn2 = datasource2.getConnection();

  UserTransaction ut = getUserTransaction();

  ut.begin();

  // 插入訂單

  // 修改庫存

  ut.commit(); // 成功的情況下,提交更新。

  } catch(SQLException ex) {

  ut.rollback(); // 失敗的情況下,回滾所有的操作

  } finally {

  conn.close();

  }

  如何獲取UserTransaction呢?可以使用如下方法

  UserTransaction tx = (UserTransaction)

  ctx.lookup("jndi/UserTransaction");

總結

以上是生活随笔為你收集整理的什么叫事务?Java如何处理事务呢?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。