MySql中的事務、JDBC事務、事務隔離級別


一、MySql事務

之前在Oracle中已經學習過事務了,這個東西就是這個東西,但是在MySql中用法還是有一點不同,正好再次回顧一下。

先看看MySql中的事務,默認情況下,每執行一條SQL語句,都是一個單獨的事務。如果需要在一個事務中包含多條SQL語句,就需要開啟和結束事務。

開始事務:start transaction

結束事務:commit或rollback

在執行SQL語句之前,先執行start transaction,這就開啟了一個新的事務,然后就可以去執行多條SQL語句,最后要結束事務,commit表示提交,即事務中多條SQL語句造成的影響會持久化到數據庫中。rollback表示回滾,一切恢復到事務的起點,事務開始之后所到的操作全當沒有發生過。

在orcale中拿銀行轉賬舉過例子,現在在MySql中實現以下:

首先建了一個銀行賬戶表

現在張三余額800,李四余額1200,下面李四向張三轉賬200.

在兩句update語句之后數據庫貌似是變了,這時候注意其他用戶看到的還是沒有變化的數據庫,因為沒有提交,這時候在本用戶查看好像是轉成功了,但是一個rollback,一切歸於開始。

二、JDBC事務

JDBC操作事務,全部都是由Connection完成。Connection的三個方法與事務有關

setAutoCommit(boolean):設置是否自動提交事務,如果不自動提交,那這句就表示事務的開始。

commit():表示提交事務

rollback():表示回滾事務

JDBC操作事務的代碼格式

try{

 con.setAutoCommit(fasle);

....

....

con.commit();

}catch(){

con.rollback();

}

如果對事務的操作拋出異常,那么肯定就執行不來,所以回滾,要是沒有出錯,那就提交。

這里一定要注意的JDBC操作事務一定要使用一個Connection對象!!!!再拿銀行轉賬來演示,首先建一個賬戶類。

import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * @author WangXinwei *使用自建工具類JdbcUntils返回Connection對象 */
public class Bank { public void account(String name,int blance) throws SQLException{ Connection conn=JdbcUntils.getConn(); String sql="update bank set blance=blance+? where name=?"; PreparedStatement ps=conn.prepareStatement(sql); ps.setInt(1, blance); ps.setString(2, name); ps.executeUpdate(); } }

使用JDBC操作事務

import java.sql.Connection; import java.sql.SQLException; /** * @author WangXinwei * 傳入轉賬方,收賬方,轉賬金額 * */
public class Demo3 { public void demo(String from, String to, int money) { Connection conn = JdbcUntils.getConn(); try { conn.setAutoCommit(false); Bank bank = new Bank(); bank.account(from, -money); bank.account(to, +money); conn.commit(); } catch (Exception e) { // TODO: handle exception
            try { conn.rollback(); conn.close(); } catch (SQLException e1) { // TODO Auto-generated catch block
 e1.printStackTrace(); } } finally { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } } } }

因為我使用的是單例模式返回的Connection對象,所以是一個對象,滿足之前說的。

三、事務的隔離級別

事務的問題一般都是出現的並發操作的時候。

並發事務問題有五種,其中兩種是更新問題,三種是讀問題。重點看並發讀問題,在這之前,先略微了解一下更新問題

1. 第一類丟失更新(lost update): 在完全未隔離事務的情況下,兩個事務更新同一條數據資源,某一事務異常終止,回滾造成第一個完成的更新也同時丟失。

2. 第二類丟失更新(second lost updates):是不可重復讀的特殊情況,如果兩個事務都讀取同一行,然后兩個都進行寫操作,並提交,第一個事務所做的改變就會丟失。

並發讀問題:

1.臟讀:讀到未提交更新數據,就是讀到另一個事務未提交數據,就是臟數據。

比如:

 

2.不可重復讀:對同一記錄兩次讀取不一致,因為另一事務對該記錄做了修改

比如:

 

3.幻讀:對同一張表的兩次查詢不一致,因為另一事務插入了一條數據

比如:

 

 不可重復讀和幻讀有什么區別呢?

不可重復讀是讀到了另一個事務的更新

幻讀是讀到了另個一表的插入(MySql中無法測試幻讀)

 四大隔離級別:

四個等級的隔離級別,在除了隔離級別不同什么都相同的情況下處理結果是不同的,因為四種隔離級別對並發數據的處理能力是不同的。

1.SERIALIZABLE(串行化)

因為是串行化,所以不會出現任何問題,效率最差

2.REPEATABLE READ(可重復讀)MySql默認

防止臟讀和不可重復讀,不能防止幻讀

3.READ COMMITTED(讀已提交數據)

防止臟讀

4.READ UNCOMMITTED(讀未提交數據)

可能出現任何問題,效率最好

查看MySql中隔離級別,使用select @@tx_isolation查看

也可以通過 set isolationlevel [4選1] 來設置隔離級別

JDBC設置隔離級別:

依舊通過Connection對象,使用方法setTransactionisolation[ int level]

參數可選為

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM