java-transaction事件

/*
########事務&數據庫連接池&DBUtils

######事務

> Transaction 其實指的一組操作,里面包含許多個單一的邏輯。
只要有一個邏輯沒有執行成功,那么都算失敗。 所有的數據都回歸到最初的狀態(回滾)

####為什么要有事務?
> 為了確保邏輯的成功。 例子: 銀行的轉賬。

?

?


###使用命令行方式演示事務。

* 開啟事務
start transaction;
* 提交或者回滾事務
commit; 提交事務, 數據將會寫到磁盤上的數據庫
rollback ; 數據回滾,回到最初的狀態。

1. 關閉自動提交功能。



2. 演示事務

?

#####使用代碼方式演示事務

> 代碼里面的事務,主要是針對連接來的。
>
>
> 1. 通過conn.setAutoCommit(false )來關閉自動提交的設置。

> 2. 提交事務 conn.commit();

> 3. 回滾事務 conn.rollback();
//注意當數據庫不支持回滾的時候有如下原因
* 1.數據庫引擎不是innodb 而是myisam,不支持事務回滾。
* 2.在rollback之前 已經通過connection.commit 提交改動 無法回滾
* 3.mysql默認create drop alter 等涉及到表修改,會隱式結束當前會話中的任何活動事務,直接提交,無法回滾。

@Test
public void testTransaction(){

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtil.getConn();

//連接,事務默認就是自動提交的。 關閉自動提交。
conn.setAutoCommit(false);

String sql = "update account set money = money - ? where id = ?";
ps = conn.prepareStatement(sql);

//扣錢, 扣ID為1 的100塊錢
ps.setInt(1, 100);
ps.setInt(2, 1);
ps.executeUpdate();


int a = 10 /0 ;

//加錢, 給ID為2 加100塊錢
ps.setInt(1, -100);
ps.setInt(2, 2);
ps.executeUpdate();

//成功: 提交事務。
conn.commit();

} catch (SQLException e) {
try {
//事變: 回滾事務
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();

}finally {
JDBCUtil.release(conn, ps, rs);
}
}

###事務的特性

* 原子性
> 指的是 事務中包含的邏輯,不可分割。

* 一致性
> 指的是 事務執行前后。數據完整性

* 隔離性
> 指的是 事務在執行期間不應該受到其他事務的影響

* 持久性
> 指的是 事務執行成功,那么數據應該持久保存到磁盤上。


###事務的安全隱患
> 不考慮隔離級別設置,那么會出現以下問題。

* 讀
> 臟讀 不可重讀讀 幻讀.
* 臟讀
> 一個事務讀到另外一個事務還未提交的數據

* 不可重復讀
> 一個事務讀到了另外一個事務提交的數據 ,造成了前后兩次查詢結果不一致。


####讀未提交 演示
1. 設置A窗口的隔離級別為 讀未提交

2. 兩個窗口都分別開啟事務

* 寫
> 丟失更新

?

#### 讀已提交演示
1. 設置A窗口的隔離級別為 讀已提交

2. A B 兩個窗口都開啟事務, 在B窗口執行更新操作。

3. 在A窗口執行的查詢結果不一致。 一次是在B窗口提交事務之前,一次是在B窗口提交事務之后。

> 這個隔離級別能夠屏蔽 臟讀的現象, 但是引發了另一個問題 ,不可重復讀。


###可串行化
> 如果有一個連接的隔離級別設置為了串行化 ,那么誰先打開了事務, 誰就有了先執行的權利, 誰后打開事務,誰就只能得著,等前面的那個事務,提交或者回滾后,才能執行。 但是這種隔離級別一般比較少用。 容易造成性能上的問題。 效率比較低。

* 按效率劃分,從高到低
> 讀未提交 > 讀已提交 > 可重復讀 > 可串行化

* 按攔截程度 ,從高到底
> 可串行化 > 可重復讀 > 讀已提交 > 讀未提交


##事務總結

###需要掌握的
1. 在代碼里面會使用事務
conn.setAutoCommit(false);
conn.commit();
conn.rollback();

2. 事務只是針對連接連接對象,如果再開一個連接對象,那么那是默認的提交。

3. 事務是會自動提交的。


###需要了解的

####安全隱患

臟讀
一個事務讀到了另一個事務未提交的數據
不可重復讀
一個事務讀到了另一個事務已提交的數據,造成前后兩次查詢結果不一致
幻讀
一個事務讀到了另一個事務insert的數據 ,造成前后查詢結果不一致 。


丟失更新。

####隔離級別

讀未提交
> 引發問題: 臟讀

讀已提交
> 解決: 臟讀 , 引發: 不可重復讀

可重復讀
> 解決: 臟讀 、 不可重復讀 , 未解決: 幻讀

可串行化
> 解決: 臟讀、 不可重復讀 、 幻讀。

mySql 默認的隔離級別是 可重復讀
Oracle 默認的隔離級別是 讀已提交


###丟失更新


###解決丟失更新
* 悲觀鎖

> 可以在查詢的時候,加入 for update
數據庫的鎖的機制,排他鎖

* 樂觀鎖
> 要求程序員自己控制。


select @@tx_isolation查看現在的隔離級別(數據庫)
set session transaction isolation level read XXX;修改隔離等級(數據庫)
XXXX參數:uncommitted 讀未提交
committed 讀已經提交
read 重復度
serializable 可串行化
*/

?

數據庫連接代碼:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class ConnLink {
//數據庫的連接部分public String jdbc_driver="com.mysql.jdbc.Driver";public String jdbc_conn="jdbc:mysql://localhost:3306/test";public String user="root";public String pass="root";//返回連接函數的部分public Connection getConn() throws SQLException, ClassNotFoundException{//1.注冊驅動
        Class.forName(jdbc_driver);//2.獲取連接Connection connection=DriverManager.getConnection(jdbc_conn,user,pass);return connection;}//釋放連接資源的部分public void relese(Connection conn,PreparedStatement pstmt) throws SQLException{if(pstmt!=null) pstmt.close();if(conn!=null) conn.close();}
}

?

?

演示代碼:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.jsp.tagext.TryCatchFinally;public class Transaction {static ConnLink connlink=new ConnLink();public static void main(String[] args) throws SQLException, ClassNotFoundException {Connection conn=null;PreparedStatement pstmt=null; try {//獲取數據庫的連接conn=connlink.getConn();//連接,事務默認就是自動提交的。 關閉自動提交。conn.setAutoCommit(false);//創建執行sql語句的對象3 書寫sql語句;String sqlString="update blank set money = money - ? where id = ?";//創建預處理對象pstmt = conn.prepareStatement(sqlString);//設置參數占位符pstmt.setInt(1, 100);pstmt.setInt(2,1); //執行語句
             pstmt.executeUpdate();//以上部分是給用戶1扣100元,我們可以理解是用戶1給用戶2轉賬100元。所以下面要給用戶2增加100元//在此處設置一個錯誤,促使數據庫的事件回滾int a=10/0;String sqlString2="update blank set money = money +  ? where id = ?";pstmt = conn.prepareStatement(sqlString2);pstmt.setInt(1, 100);pstmt.setInt(2,2); pstmt.executeUpdate();//由于上面的conn.setAutoCommit(false);設置成了flase所以此處需要用commit()進行提交
             conn.commit();} catch (SQLException e) {// TODO: handle exception//這里是出現意外的情況就是轉賬失敗,那么怎么辦呢,直接取消所有的操作,實現數據庫的回滾。
                conn.rollback();e.printStackTrace();}finally{connlink.relese(conn, pstmt);}}
}

?

轉載于:https://www.cnblogs.com/byczyz/p/11343280.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/386206.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/386206.shtml
英文地址,請注明出處:http://en.pswp.cn/news/386206.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

阿里P8親自講解!java實例變量和類變量

前言 Spring如何解決的循環依賴,是近兩年流行起來的一道Java面試題。其實筆者本人對這類框架源碼題還是持一定的懷疑態度的。如果筆者作為面試官,可能會問一些諸如“如果注入的屬性為null,你會從哪幾個方向去排查”這些場景題。那么既然寫了…

java---連接池的學習

/** ####################################數據庫的連接池學習################################# * * * #####數據庫連接池 >1. 數據庫的連接對象創建工作,比較消耗性能。 >2.一開始現在內存中開辟一塊空間(集合) , 一開…

阿里P8親自講解!成功入職頭條月薪35K

前言 又到一年金九銀十之際。 Java作為目前用戶最多,使用范圍最廣的軟件開發技術之一。 Java的技術體系主要由支撐Java程序運行的虛擬機,提供各開發領域接口支持的Java,Java編程語言及許多第三方Jvav框架構成。 其中,以Java的虛擬器為今天的著…

java----連接池C3p0使用的補充

C3p0數據庫的連接方式是目前市場場最為廣泛的類型之一 本篇主要你演示C3p0使用文件配置和不使用文件配置的兩種操作方式 #######使用文件配置 import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;import com.dbutil.zyz.ConnLink; …

阿里P8大佬親自教你!java程序設計第四版pdf

前言 最近有很多朋友去目前主流的大型互聯網公司面試(阿里巴巴、京東、字節跳動、螞蟻金服、滴滴),面試回來之后會發給我一些面試題。有些朋友輕松過關,拿到offer,但是有一些是來詢問我答案的。 我特意整理了一下&am…

阿里P8大佬親自講解!朝陽java培訓

開頭 Spring框架自誕生以來一直備受開發者青睞,有人親切的稱之為:Spring 全家桶。Spring更是避免了重復造輪子的工作并跟隨著互聯網行業的發展做出不斷的更新,很多研發人員把spring看作心目中最好的Java項目,沒有之一。 **可以毫…

分隔符的作用和用法

一、插入分頁符 當文本或圖形等內容填滿一頁時,Word會插入一個自動分頁符并開始新的一頁。如果要在某個特定位置強制分頁,可插入“手動”分頁符,這樣可以確保章節標題總在新的一頁開始。首先,將插入點置于要插入分頁符的位置&…

java----DBUtils知識點補充

dbutils 只是幫我們簡化了CRUD 的代碼, 但是連接的創建以及獲取工作。 不在他的考慮范圍 QueryRunner主要是這個類 import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import com.mchange.v2.c3p0.ComboPooledDataSource;public class D…

大廠offer手到擒來,Java面試真題精選

前言 事務我們都知道是什么,而Spring事務就是在數據庫之上利用AOP提供聲明式事務和編程式事務幫助我們簡化開發,解耦業務邏輯和系統邏輯。但是Spring事務原理是怎樣?事務在方法間是如何傳播的?為什么有時候事務會失效&#xff1f…

大廠也在用的6種數據脫敏方案,醍醐灌頂!

前言 由于作者面試過程中高度緊張,本文中只列出了自己還記得的部分題目。 經歷了漫長一個月的等待,終于在前幾天通過面試官獲悉已被螞蟻金服錄取,這期間的焦慮、痛苦自不必說,知道被錄取的那一刻,一整年的陰霾都一掃…

大牛帶你直擊優秀開源框架靈魂,給大家安排上!

前言 微架構的出現,很好地適應了這個時代對快速發展變化的要求。它不再提倡一體化的項目設計,而是對項目進行有效的“業務區”(可以簡單理解為不同的子系統〉劃分,并利用合理的技術對業務性能做出提升和改善,同時又極大地簡化了配…

大牛用SSM框架實現了支付寶的支付功能,滿滿干貨指導

前言 現在刷抖音經常可以看到一些老外街坊,問他們最想把什么帶回自己的國家,我聽過很多的回答都是:淘寶,支付寶,美食,微信,外賣,高鐵等等。 確實如此,隨著國家的快速發…

java---Listener Filter知識點學習

##Listener > 監聽器 * 能做什么事? > 監聽某一個事件的發生。 狀態的改變。 * 監聽器的內部機制 > 其實就是接口回調. ####接口回調 * 需求: > A在執行循環,當循環到5的時候, 通知B。 > 事先先把一個對象傳遞給 …

頭條三面技術四面HR,就是這么簡單

前言 看日期,今天都是4月了,這春招也差不多進入尾聲了。 近期任有不少朋友都在找工作,很多人開始抱怨,工作可真難找啊!身邊不少朋友問我咋搞呀,秋招都要結束了,工作還沒著落呢…額…這個…今年…

臨時表

tmp_table_size 這個配置限制了內存臨時表的大小,默認值是 16M。 如果臨時表大小超過了 tmp_table_size,那么內存臨時表就會轉成磁盤臨時表 磁盤臨時表使用的引擎默認是 InnoDB,是由參數 internal_tmp_disk_storage_engine 控制的。 轉載于:h…

如何保證Redis與數據庫的雙寫一致性?進階加薪全靠它!

我有話要說,請仔細看完 我發現一個現象,很多開發5年的程序員仍然停留在crud的階段,這是什么原因? 最主要的原因就是基礎很差,尤其對于JVM和并發編程這方面掌握的比較差,而JVM和并發編程就是非常非常重要的…

Swimming Balls

Swimming Balls https://vjudge.net/contest/318752#problem/J如果直接算,各種球的情況都不清楚,因為放一個球之后,水位的變化也會影響之前放入的球,不如,二分最終的水位高度,這樣每個球的貢獻就有了 #incl…

如何保證redis高可用?薪資翻倍

前言: 首先介紹一下我的同學,專科畢業應用電子技術專業,已經畢業快兩年了。因為專業的原因工作一年覺得沒什么發展前途就想轉行,身為他的“好基友”,他覺得我這個工作挺好的,就咨詢了我一下,經…

Linux中強大的輸入輸出重定向和管道

Linux中有三個最重要的輸入輸出流: Standard Input(STDIN) - 通常指鍵盤的輸入 Standard Output(STDOUT) - 通常指顯示器的輸出 Standard Error(STDERR) - 通常也是重定向到顯示器 默認情況下,分別是0表示標準輸入(stdin),1表示標準輸出(stdout),2表示標準錯誤。 參…

如何保證消息隊列的高可用?透徹分析源碼

前言 成為優秀的架構師是大部分初中級工程師的階段性目標。優秀的架構師往往具備七種核心能力:編程能力、調試能力、編譯部署能力、性能優化能力、業務架構能力、在線運維能力、項目管理能力和規劃能力。 這幾種能力之間的關系大概如下圖。編程能力、調試能力和編…