Java -- JDBC 事務處理, 事務的隔離級別 臟讀 不可重復讀 等...


1. 事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功

數據庫開啟事務命令
start transaction  開啟事務
Rollback  回滾事務
Commit   提交事務
JDBC控制事務語句
Connection.setAutoCommit(false);  //start transaction
Connection.rollback();  //rollback
Connection.commit();  //commit
設置事務回滾點
Savepoint sp = conn.setSavepoint();
Conn.rollback(sp);
Conn.commit();  // 回滾后必須要提交
public class Demo1 {

	/**
	 * 模似轉帳
	  
create table account(
	id int primary key auto_increment,
	name varchar(40),
	money float
)character set utf8 collate utf8_general_ci;

insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);
	 
	 */
	public static void main(String[] args) {
		
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try{
			conn = JdbcUtils_C3P0.getConnection();
			conn.setAutoCommit(false);   //start transaction
			
			String sql1 = "update account set money=money-100 where name='aaa'";
			st = conn.prepareStatement(sql1);
			st.executeUpdate();
						
			String sql2 = "update account set money=money+100 where name='bbb'";
			st = conn.prepareStatement(sql2);
			st.executeUpdate();
						
			conn.commit();
			
			System.out.println("成功!!!");  
			
		}catch (Exception e) {   //中途異常 自動回滾
			e.printStackTrace();
		}finally{
			JdbcUtils_C3P0.release(conn, st, rs);
		}		
	}

}
public class Demo2 {
	public static void main(String[] args) {
		
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		Savepoint sp = null;
		
		try{
			conn = JdbcUtils.getConnection();
			conn.setAutoCommit(false);   //start transaction
			
			String sql1 = "update account set money=money-100 where name='aaa'";
			st = conn.prepareStatement(sql1);
			st.executeUpdate();
			
			sp = conn.setSavepoint();   //設置事務回滾點
			
			String sql2 = "update account set money=money+100 where name='bbb'";
			st = conn.prepareStatement(sql2);
			st.executeUpdate();
			
			int x = 1/0;  //異常觸發
			
			String sql3 = "update account set money=money+100 where name='ccc'"; 
			st = conn.prepareStatement(sql3);
			st.executeUpdate();
			
			conn.commit();
			
		}catch (Exception e) {
			try {
				conn.rollback(sp);  //回滾到設置點
				conn.commit();  //回滾了要記得提交
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			JdbcUtils.release(conn, st, rs);
		}
		
	}

}

2. 事務的特性(ACID)
原子性( Atomicity ): 原子性是指事務是一個不可分割的工作單位,事務中的操作要么都發生,要么都不發生。 
一致性( Consistency ): 事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。
隔離性( Isolation ): 事務的隔離性是多個用戶並發訪問數據庫時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作數據所干擾,多個並發事務之間要相互隔離。
持久性( Durability ): 持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響。

3. 事務的隔離級別
臟讀: 指一個事務讀取了另外一個事務未提交的數據。
不可重復讀: 在一個事務內讀取表中的某一行數據,多次讀取結果不同(另一個事務已經提交)。
虛讀 ( 幻讀 ): 是指在一個事務內讀取到了別的事務插入的數據,導致前后讀取不一致。
數據庫共定義了四種隔離級別
Serializable :可避免臟讀、不可重復讀、虛讀情況的發生。(串行化)
Repeatable read :可避免臟讀、不可重復讀情況的發生。(可重復 ( 默認 )
Read committed :可避免臟讀情況發生(讀已提交)。
Read uncommitted :最低級別,以上情況均無法保證。 ( 讀未提交 )
set   transaction isolation level 設置事務隔離級別
select @@tx_isolation  查詢當前事務隔離級別
 
public class Demo3 {

	/**
	 * 設置事務隔離級別
	 * 寫一個查詢程序
	 */
	public static void main(String[] args) {
		
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try{
			conn = JdbcUtils.getConnection();
			conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); //設置隔離等級
			conn.setAutoCommit(false); //開啟事務
			
			String sql = "select * from account where name='aaa'";
			st = conn.prepareStatement(sql);
			rs = st.executeQuery();
			rs.next();
			System.out.println(rs.getFloat("money"));			
			
			Thread.sleep(1000*10);
			
			rs = st.executeQuery();
			rs.next();
			System.out.println(rs.getFloat("money"));
			
			Thread.sleep(1000*10);
			
			rs = st.executeQuery();
			rs.next();
			System.out.println(rs.getFloat("money"));
		
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			JdbcUtils.release(conn, st, rs);
		}
	}
}

 

 


免責聲明!

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



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