什么是Java事務(wù)

成都創(chuàng)新互聯(lián)專注于漢源網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供漢源營銷型網(wǎng)站建設(shè),漢源網(wǎng)站制作、漢源網(wǎng)頁設(shè)計、漢源網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造漢源網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供漢源網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
通常的觀念認(rèn)為,事務(wù)僅與數(shù)據(jù)庫相關(guān)。
事務(wù)必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)、一致性(consistency)、隔離性(isolation)和持久性(durability)的縮寫。事務(wù)的原子性表示事務(wù)執(zhí)行過程中的任何失敗都將導(dǎo)致事務(wù)所做的任何修改失效。一致性表示當(dāng)事務(wù)執(zhí)行失敗時,所有被該事務(wù)影響的數(shù)據(jù)都應(yīng)該恢復(fù)到事務(wù)執(zhí)行前的狀態(tài)。隔離性表示在事務(wù)執(zhí)行過程中對數(shù)據(jù)的修改,在事務(wù)提交之前對其他事務(wù)不可見。持久性表示已提交的數(shù)據(jù)在事務(wù)執(zhí)行失敗時,數(shù)據(jù)的狀態(tài)都應(yīng)該正確。
通俗的理解,事務(wù)是一組原子操作單元,從數(shù)據(jù)庫角度說,就是一組SQL指令,要么全部執(zhí)行成功,若因為某個原因其中一條指令執(zhí)行有錯誤,則撤銷先前執(zhí)行過的所有指令。更簡答的說就是:要么全部執(zhí)行成功,要么撤銷不執(zhí)行。
既然事務(wù)的概念從數(shù)據(jù)庫而來,那Java事務(wù)是什么?之間有什么聯(lián)系?
實際上,一個Java應(yīng)用系統(tǒng),如果要操作數(shù)據(jù)庫,則通過JDBC來實現(xiàn)的。增加、修改、刪除都是通過相應(yīng)方法間接來實現(xiàn)的,事務(wù)的控制也相應(yīng)轉(zhuǎn)移到Java程序代碼中。因此,數(shù)據(jù)庫操作的事務(wù)習(xí)慣上就稱為Java事務(wù)。
事務(wù)的特性:
1) 原子性(atomicity):事務(wù)是數(shù)據(jù)庫的邏輯工作單位,而且是必須是原子工作單位,對于其數(shù)據(jù)修改,要么全部執(zhí)行,要么全部不執(zhí)行。
2) 一致性(consistency):事務(wù)在完成時,必須是所有的數(shù)據(jù)都保持一致狀態(tài)。在相關(guān)數(shù)據(jù)庫中,所有規(guī)則都必須應(yīng)用于事務(wù)的修改,以保持所有數(shù)據(jù)的完整性。
3) 隔離性(isolation):一個事務(wù)的執(zhí)行不能被其他事務(wù)所影響。
4) 持久性(durability):一個事務(wù)一旦提交,事物的操作便永久性的保存在DB中。即使此時再執(zhí)行回滾操作也不能撤消所做的更改。
事務(wù)(Transaction):是并發(fā)控制的單元,是用戶定義的一個操作序列。這些操作要么都做,要么都不做,是一個不可分割的工作單位。通過事務(wù),sql server 能將邏輯相關(guān)的一組操作綁定在一起,以便服務(wù)器 保持?jǐn)?shù)據(jù)的完整性。事務(wù)通常是以begin transaction開始,以commit或rollback結(jié)束。Commint表示提交,即提交事務(wù)的所有操作。具體地說就是將事務(wù)中所有對數(shù)據(jù)的更新寫回到磁盤上的物理數(shù)據(jù)庫中去,事務(wù)正常結(jié)束。Rollback表示回滾,即在事務(wù)運行的過程中發(fā)生了某種故障,事務(wù)不能繼續(xù)進(jìn)行,系統(tǒng)將事務(wù)中對數(shù)據(jù)庫的所有已完成的操作全部撤消,滾回到事務(wù)開始的狀態(tài)。
自動提交事務(wù):每條單獨的語句都是一個事務(wù)。每個語句后都隱含一個commit。 (默認(rèn))
顯式事務(wù):以begin transaction顯示開始,以commit或rollback結(jié)束。
隱式事務(wù):當(dāng)連接以隱式事務(wù)模式進(jìn)行操作時,sql server數(shù)據(jù)庫引擎實例將在提交或回滾當(dāng)前事務(wù)后自動啟動新事務(wù)。無須描述事物的開始,只需提交或回滾每個事務(wù)。但每個事務(wù)仍以commit或rollback顯式結(jié)束。連接將隱性事務(wù)模式設(shè)置為打開之后,當(dāng)數(shù)據(jù)庫引擎實例首次執(zhí)行下列任何語句時,都會自動啟動一個隱式事務(wù):alter table,insert,create,open ,delete,revoke ,drop,select, fetch ,truncate table,grant,update在發(fā)出commit或rollback語句之前,該事務(wù)將一直保持有效。在第一個事務(wù)被提交或回滾之后,下次當(dāng)連接執(zhí)行以上任何語句時,數(shù)據(jù)庫引擎實例都將自動啟動一個新事務(wù)。該實例將不斷地生成隱性事務(wù)鏈,直到隱性事務(wù)模式關(guān)閉為止。
JDBC事務(wù)管理
在使用JDBC的時候, 如何進(jìn)行事務(wù)的管理。直接看一下代碼
示例代碼
/**
* @Title: JDBCTrans.java
* @Package com.oscar999.trans
* @Description:
* @author XM
* @date Feb 14, 2017 4:38:27 PM
* @version V1.0
*/
package com.oscar999.trans;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author
*
*/
public class JDBCTrans {
public JDBCTrans() {
}
/**
*
* @param sHostName
* @param sPortNumber
* @param sSid
* @param userName
* @param password
* @return
* @throws SQLException
*/
public Connection getConnection(String sHostName, String sPortNumber, String sSid, String userName, String password) throws SQLException {
Connection conn = null;
String url = getOraclURL(sHostName, sPortNumber, sSid);
conn = DriverManager.getConnection(url,userName,password);
return conn;
}
/**
*
* @param conn
* @param sql
* @throws SQLException
*/
public void add(Connection conn, String sql) throws SQLException {
Statement stmt = null;
try {
stmt = conn.createStatement();
stmt.execute(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (stmt != null)
stmt.close();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String sHostName = "";
String sPortNumber = "";
String sSid = "";
String userName = "";
String password = "";
sHostName = "";
sPortNumber = "";
sSid = "";
userName = "";
password = "";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
JDBCTrans jdbcTrans = new JDBCTrans();
Connection conn = null;
try {
conn = jdbcTrans.getConnection(sHostName, sPortNumber, sSid, userName, password);
conn.setAutoCommit(false);// can't insert, update
//1. add SQL
String addSQL = "insert into TEST_TABLE values('name1','value1')";
jdbcTrans.add(conn,addSQL);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
/*if (conn != null)
{
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
}
}
private String getOraclURL(String sHostName, String sPortNumber, String sSid) {
String url = "jdbc:oracle:thin:@" + sHostName + ":" + sPortNumber + ":" + sSid;
return url;
}
} 針對以上代碼, 說明如下:
以上代碼有幾點說明的部分:
1. conn.setAutoCommit(false) 執(zhí)行之后不提交事務(wù)。
對于Select沒有影響, 但對于Insert和Update的話, 沒有提交數(shù)據(jù)就不會被修改
2. conn.close(); 關(guān)閉Connection的代碼有被Mark掉, 是想呈現(xiàn)conn.setAutoCommit(false)的效果。
原因是在 Connection Close的時候會執(zhí)行一次Commit.
而如果Connection是在應(yīng)用服務(wù)器中使用連接池的話, Connection就不會被Close, 也就不會執(zhí)行Commit.
3. setAutoCommit(false) 用法大多數(shù)是在要執(zhí)行多條語句才提交。
所以針對以上第三點, 更接近實際的狀況的代碼如示例代碼2
示例代碼2
/**
* @Title: JDBCTrans.java
* @Package com.oscar999.trans
* @Description:
* @author XM
* @date Feb 14, 2017 4:38:27 PM
* @version V1.0
*/
package com.oscar999.trans;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author
*
*/
public class JDBCTrans {
public JDBCTrans() {
}
/**
*
* @param sHostName
* @param sPortNumber
* @param sSid
* @param userName
* @param password
* @return
* @throws SQLException
*/
public Connection getConnection(String sHostName, String sPortNumber, String sSid, String userName, String password) throws SQLException {
Connection conn = null;
String url = getOraclURL(sHostName, sPortNumber, sSid);
conn = DriverManager.getConnection(url, userName, password);
return conn;
}
/**
*
* @param conn
* @param sql
* @throws SQLException
*/
public void add(Connection conn, String sql) throws SQLException {
Statement stmt = null;
try {
stmt = conn.createStatement();
stmt.execute(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (stmt != null)
stmt.close();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String sHostName = "";
String sPortNumber = "";
String sSid = "";
String userName = "";
String password = "";
sHostName = "";
sPortNumber = "";
sSid = "";
userName = "";
password = "";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
JDBCTrans jdbcTrans = new JDBCTrans();
Connection conn = null;
try {
conn = jdbcTrans.getConnection(sHostName, sPortNumber, sSid, userName, password);
conn.setAutoCommit(false);// can't insert, update
// 1. add SQL 1
String addSQL = "insert into TEST_TABLE values('name1','value1')";
jdbcTrans.add(conn, addSQL);
//2. add SQL 2
addSQL = "insert into TEST_TABLE values('name2','value2')";
jdbcTrans.add(conn, addSQL);
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
if(conn!=null){
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private String getOraclURL(String sHostName, String sPortNumber, String sSid) {
String url = "jdbc:oracle:thin:@" + sHostName + ":" + sPortNumber + ":" + sSid;
return url;
}
} 這里需要說明的是: conn.rollback();
只要執(zhí)行有異常,就要rollback , 這一步必不可少
如果沒有在執(zhí)行出現(xiàn)異常的時候進(jìn)行回滾。如果在執(zhí)行第一條語句之后出現(xiàn)異常,con既沒有提交也沒有回滾,表就會被鎖住(如果oracle數(shù)據(jù)庫就是行鎖),而這個鎖卻沒有機會釋放。
可能在執(zhí)行con.close()的時候會釋放鎖,但還是如果應(yīng)用服務(wù)器使用了數(shù)據(jù)庫連接池,連接不會被斷開。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家學(xué)習(xí)或者使用java能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對創(chuàng)新互聯(lián)的支持。
分享文章:Java事務(wù)管理學(xué)習(xí)之JDBC詳解
網(wǎng)頁網(wǎng)址:http://chinadenli.net/article34/gdgjse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司、做網(wǎng)站、網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站、小程序開發(fā)、外貿(mào)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)