java事務,java事務註解

本文目錄一覽:

在java中,事務是什麼?有什麼用!

一、什麼是Java事務

通常的觀念認為,事務僅與資料庫相關。

事務必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)、一致性(consistency)、隔離性

(isolation)和持久性(durability)的縮寫。事務的原子性表示事務執行過程中的任何失敗都將導致事務所做的任何修改失效。一致性表示

當事務執行失敗時,所有被該事務影響的數據都應該恢復到事務執行前的狀態。隔離性表示在事務執行過程中對數據的修改,在事務提交之前對其他事務不可見。持

久性表示已提交的數據在事務執行失敗時,數據的狀態都應該正確。

通俗的理解,事務是一組原子操作單元,從資料庫角度說,就是一組SQL指令,要麼全部執行成功,若因為某個原因其中一條指令執行有錯誤,則撤銷先前執行過的所有指令。更簡答的說就是:要麼全部執行成功,要麼撤銷不執行。

既然事務的概念從資料庫而來,那Java事務是什麼?之間有什麼聯繫?

實際上,一個Java應用系統,如果要操作資料庫,則通過JDBC來實現的。增加、修改、刪除都是通過相應方法間接來實現的,事務的控制也相應轉移到Java程序代碼中。因此,資料庫操作的事務習慣上就稱為Java事務。

二、為什麼需要事務

事務是為解決數據安全操作提出的,事務控制實際上就是控制數據的安全訪問。具一個簡單例子:比如銀行轉帳業務,賬戶A要將自己賬戶上的1000元

轉到B賬戶下面,A賬戶餘額首先要減去1000元,然後B賬戶要增加1000元。假如在中間網路出現了問題,A賬戶減去1000元已經結束,B因為網路中

斷而操作失敗,那麼整個業務失敗,必須做出控制,要求A賬戶轉帳業務撤銷。這才能保證業務的正確性,完成這個操走就需要事務,將A賬戶資金減少和B賬戶資

金增加方到一個事務裡面,要麼全部執行成功,要麼操作全部撤銷,這樣就保持了數據的安全性。

三、Java事務的類型

Java事務的類型有三種:JDBC事務、JTA(Java Transaction API)事務、容器事務。

1、JDBC事務

JDBC 事務是用 Connection 對象控制的。JDBC Connection 介面( java.sql.Connection )提供了兩種事務模式:自動提交和手工提交。 java.sql.Connection 提供了以下控制事務的方法:

public void setAutoCommit(boolean)

public boolean getAutoCommit()

public void commit()

public void rollback()

使用 JDBC 事務界定時,您可以將多個 SQL 語句結合到一個事務中。JDBC 事務的一個缺點是事務的範圍局限於一個資料庫連接。一個 JDBC 事務不能跨越多個資料庫。

2、JTA(Java Transaction API)事務

JTA是一種高層的,與實現無關的,與協議無關的API,應用程序和應用伺服器可以使用JTA來訪問事務。

JTA允許應用程序執行分散式事務處理–在兩個或多個網路計算機資源上訪問並且更新數據,這些數據可以分布在多個資料庫上。JDBC驅動程序的JTA支持極大地增強了數據訪問能力。

如果計劃用 JTA 界定事務,那麼就需要有一個實現 javax.sql.XADataSource 、

javax.sql.XAConnection 和 javax.sql.XAResource 介面的 JDBC

驅動程序。一個實現了這些介面的驅動程序將可以參與 JTA 事務。一個 XADataSource 對象就是一個 XAConnection

對象的工廠。 XAConnection s 是參與 JTA 事務的 JDBC 連接。

您將需要用應用伺服器的管理工具設置 XADataSource 。從應用伺服器和 JDBC 驅動程序的文檔中可以了解到相關的指導。

J2EE 應用程序用 JNDI 查詢數據源。一旦應用程序找到了數據源對象,它就調用 javax.sql.DataSource.getConnection() 以獲得到資料庫的連接。

XA 連接與非 XA 連接不同。一定要記住 XA 連接參與了 JTA 事務。這意味著 XA 連接不支持 JDBC

的自動提交功能。同時,應用程序一定不要對 XA 連接調用 java.sql.Connection.commit() 或者

java.sql.Connection.rollback() 。相反,應用程序應該使用 UserTransaction.begin()、

UserTransaction.commit() 和 serTransaction.rollback() 。

3、容器事務

容器事務主要是J2EE應用伺服器提供的,容器事務大多是基於JTA完成,這是一個基於JNDI的,相當複雜的API實現。相對編碼實現JTA事

務管理,我們可以通過EJB容器提供的容器事務管理機制(CMT)完成同一個功能,這項功能由J2EE應用伺服器提供。這使得我們可以簡單的指定將哪個方

法加入事務,一旦指定,容器將負責事務管理任務。這是我們土建的解決方式,因為通過這種方式我們可以將事務代碼排除在邏輯編碼之外,同時將所有困難交給

J2EE容器去解決。使用EJB CMT的另外一個好處就是程序員無需關心JTA API的編碼,不過,理論上我們必須使用EJB。

四、三種事務差異

1、JDBC事務控制的局限性在一個資料庫連接內,但是其使用簡單。

2、JTA事務的功能強大,事務可以跨越多個資料庫或多個DAO,使用也比較複雜。

3、容器事務,主要指的是J2EE應用伺服器提供的事務管理,局限於EJB應用使用。

五、總結

事務控制是構建J2EE應用不可缺少的一部分,合理選擇應用何種事務對整個應用系統來說至關重要。一般說來,在單個JDBC

連接連接的情況下可以選擇JDBC事務,在跨多個連接或者資料庫情況下,需要選擇使用JTA事務,如果用到了EJB,則可以考慮使用EJB容器事務。

如果滿意請及時採納,謝謝~

java 資料庫事務與應用事務的區別

在說他們之間的區別之前,先考慮如下幾個問題:

1、getCurrentSession()與openSession()的區別?

* 採用getCurrentSession()創建的session會綁定到當前線程中,而採用openSession()

創建的session則不會

* 採用getCurrentSession()創建的session在commit或rollback時會自動關閉,而採用openSession()

創建的session必須手動關閉

2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:

* 如果使用的是本地事務(jdbc事務)

property name=”hibernate.current_session_context_class”thread/property

* 如果使用的是全局事務(jta事務)

property name=”hibernate.current_session_context_class”jta/property

以上是hibernate中一些使用,下面來說說jdbc與jta的區別:

JDBC 事務

JDBC 事務是用 Connection 對象控制的。JDBC Connection 介面( java.sql.Connection )提供了兩種事務模式:自動提交和手工提交。

#在jdbc中,事務操作預設是自動提交。也就是說,一條對資料庫的更新表達式代表一項事務操作,操作成功後,系統將自動調用commit()來提交,否則將調用rollback()來回滾。

# 在jdbc中,可以通過調用setAutoCommit(false)來禁止自動提交。之後就可以把多個資料庫操作的表達式作為一個事務,在操作完成後調 用commit()來進行整體提交,倘若其中一個表達式操作失敗,都不會執行到commit(),並且將產生響應的異常;此時就可以在異常捕獲時調用 rollback()進行回滾。這樣做可以保持多次更新操作後,相關數據的一致性,示例如下:

try {

conn =

DriverManager.getConnection

(“jdbc:oracle:thin:@host:1521:SID”,”username”,”userpwd”;

conn.setAutoCommit(false);//禁止自動提交,設置回滾點

stmt = conn.createStatement();

stmt.executeUpdate(「alter table …」); //資料庫更新操作1

stmt.executeUpdate(「insert into table …」); //資料庫更新操作2

conn.commit(); //事務提交

}catch(Exception ex) {

ex.printStackTrace();

try {

conn.rollback(); //操作不成功則回滾

}catch(Exception e) {

e.printStackTrace();

}

}

JDBC 事務的一個缺點是事務的範圍局限於一個資料庫連接。一個 JDBC 事務不能跨越多個資料庫。

JTA事務

JTA(Java Transaction API) 為 J2EE 平台提供了分散式事務服務。

要用 JTA 進行事務界定,應用程序要調用 javax.transaction.UserTransaction 介面中的方法。例如:

utx.begin();

// …

DataSource ds = obtainXADataSource();

Connection conn = ds.getConnection();

pstmt = conn.prepareStatement(“UPDATE MOVIES …”);

pstmt.setString(1, “Spinal Tap”);

pstmt.executeUpdate();

// …

utx.commit();

讓我們來關注下面的話:

「用 JTA 界定事務,那麼就需要有一個實現 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 介面的 JDBC 驅動程序。一個實現了這些介面的驅動程序將可以參與 JTA 事務。一個 XADataSource 對象就是一個 XAConnection 對象的工廠。 XAConnection s 是參與 JTA 事務的 JDBC 連接。」

要使用JTA事務,必須使用XADataSource來產生資料庫連接,產生的連接為一個XA連接。

XA連接(javax.sql.XAConnection)和非XA(java.sql.Connection)連接的區別在於:XA可以參與JTA的事務,而且不支持自動提交。

注意:

Oracle, Sybase, DB2, SQL Server等大型資料庫才支持XA, 支持分布事務。

My SQL 連本地都支持不好,更別說分布事務了。

JTA方式的實現過程:

用XADataSource產生的XAConnection它擴展了一個getXAResource()方法,事務通過這個方法把它加入到事務容器中進行 管理.對於調用者來說,根本看不到事務是如果管理的,你只要聲明開始事務,告訴容器我下面的操作要求事務參與了,最後告訴事務說到這兒可以提交或回滾了, 別的都是黑箱操作。

在使用JTA之前,你必須首先實現一個Xid類用來標識事務(在普通情況下這將由事務管理程序來處理)。Xid包含三個元素:formatID、gtrid(全局事務標識符)和bqual(分支修飾詞標識符)。

下面的例子說明Xid的實現:

import javax.transaction.xa.*;

public class MyXid implements Xid

{

protected int formatId;

protected byte gtrid[];

protected byte bqual[];

public MyXid()

{

}

public MyXid(int formatId, byte gtrid[], byte bqual[])

{

this.formatId = formatId;

this.gtrid = gtrid;

this.bqual = bqual;

}

public int getFormatId()

{

return formatId;

}

public byte[] getBranchQualifier()

{

return bqual;

}

public byte[] getGlobalTransactionId()

{

return gtrid;

}

}

其次,你需要創建一個你要使用的資料庫的數據源:

public DataSource getDataSource()

throws SQLException

{

SQLServerDataSource xaDS = new

com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource();

xaDS.setDataSourceName(“SQLServer”);

xaDS.setServerName(“server”);

xaDS.setPortNumber(1433);

xaDS.setSelectMethod(“cursor”);

return xaDS;

}

例1 這個例子是用「兩步提交協議」來提交一個事務分支:

XADataSource xaDS;

XAConnection xaCon;

XAResource xaRes;

Xid xid;

Connection con;

Statement stmt;

int ret;

xaDS = getDataSource();

xaCon = xaDS.getXAConnection(“jdbc_user”, “jdbc_password”);

xaRes = xaCon.getXAResource();

con = xaCon.getConnection();

stmt = con.createStatement();

xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});

try {

xaRes.start(xid, XAResource.TMNOFLAGS);

stmt.executeUpdate(“insert into test_table values (100)”);

xaRes.end(xid, XAResource.TMSUCCESS);

ret = xaRes.prepare(xid);

if (ret == XAResource.XA_OK) {

xaRes.commit(xid, false);

}

}

catch (XAException e) {

e.printStackTrace();

}

finally {

stmt.close();

con.close();

xaCon.close();

}

當然,實際過程中,我們不需要寫這些代碼,這些代碼是JTA最終的實現代碼。

關於「兩步提交協議」,可以參看下面的文章:

兩階段提交(Two-Phase-Commit)協議

首先,兩階段提交(Two-Phase-Commit)事務的啟動與常規的單階段提交(One-Phase-Commit)事務類似。接著,應用程序/客 戶機對該兩階段提交(Two-Phase-Commit)操作中所涉及的所有資料庫執行其修改工作。現在,在最終提交該事務之前,客戶機通知參與的資料庫準備提交(第 1 階段)。如果客戶機從資料庫收到一條「okay」,就發出命令向資料庫提交該事務(第 2 階段)。最後分散式事務(Distributed Transaction)結束。

上面的例子演示了如何在 Java 中使用 JTA 實現兩階段提交(Two-Phase-Commit)協議。在該應用程序中,如果一個事務分支報告了錯誤,您就要負責進行錯誤處理。但是「兩階段提交協議 簡介」小節中提到仍然存在一個問題,那就是如果第 2 階段中一個事務分支發生故障,該怎麼辦呢?

如果再次查看程序代碼,您可以看到在「第 1 階段」和「第 2 階段」之間有一個很小的時間間隔。在這一時間間隔中,出於某種理由,其中某一參與資料庫可能崩潰。如果發生了,我們將陷入分散式事務已經部分提交的情形中。

假 定下列情形:在「第 1 階段」之後,您從 DB2 和 IDS 資料庫中都收到了「okay」。在下一步中,應用程序成功提交了 DB2 的事務分支。接著,應用程序通知 DB2 事務分支提交事務。現在,在應用程序可以通知 IDS 事務分支提交它這一部分之前,IDS 引擎由於斷電發生崩潰。這就是一種部分提交全局事務的情形。您現在該怎麼辦呢?

在重啟之後,DB2 和 IDS 都將嘗試恢復打開的事務分支。該引擎等待來自應用程序的提示如何做。如果應用程序沒有準備重新發送「第 2 階段」的提交,該事務分支將被引擎所啟動的試探性回滾中止。這是非常糟糕的,因為這將使該全局事務處於不一致狀態。

一種解決方案是用一個小型應用程序連接引擎中打開的事務分支,並通知引擎提交或回滾這一打開的事務。如果您使用 IDS 作為後端,那麼還有一個隱藏的 onmode 標誌,允許您結束打開的事務分支。(onmode -Z xid)。

在 DB2 UDB 中,您可以發出 LIST INDOUBT TRANSACTIONS 來獲得打開的 XA 事務的有關信息。您必須查看 DB2 Information Center 中的描述來解決該問題。

上面描述的情形是一個很好的例子,也是使用應用程序伺服器(Application Server)或事務監控器(Transaction Monitor)的理由。在使用一個中間層伺服器時,就由該伺服器負責保持事情正常。

java中的事務

如果你用Spring框架,Spring中可以實現事務管理,在spring 配置文件中配置事務管理器,也可以使用Spring註解式事務,在方法上加上@Transactional註解。

@Transactional

public void save() {

//你的代碼邏輯

}

如果沒有使用Spring框架,可以用JDBC處理事務,如下:

try{

con.setAutoCommit(false);//開啟事務 ……

con.commit();//try的最後提交事務

} catch() {

con.rollback();//回滾事務

}

java中怎麼控制事務的一致性

Java中為了控制事務的一致性,會使用插入回滾點、callback方法,保證數據不被篡改,示例如下:

public String delete(String id) {

String ID = id;

 db = new getConnection();

 Connection con = db.getConnection();

 try {

con.setAutoCommit(false);

db.executeUpdate(“delete from helloworld where ID=” + ID); //更新操作1

db.executeUpdate(“delete from helloworld _book where ID=” + ID); //更新操作2

db.executeUpdate(“delete from helloworld_user where ID=” + ID); //更新操作3

con.commit();//提交JDBC事務

con.setAutoCommit(true);

db.close();

return 「success」;

 }

 catch (Exception e) {

con.rollBack();//回滾JDBC事務

e.printStackTrace();

db.close();

return 「fail」;

}

}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/239472.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:16
下一篇 2024-12-12 12:17

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論