• 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);
    		}
    	}
    }
    

     
  • 相关阅读:
    BUAA_OO_2020_Unit3 Summary
    BUAA_OO_2020_Unit2 Summary
    DataFrame的遍历
    ESMM提升CVR的论文summary
    FaceBook 关于提升CTR的论文研究
    OO终章·GRAND BATTLE
    第三单元规格作业博客总结
    OO电梯单元作业总结
    【OO多项式求导作业总结】
    提问回顾与个人总结
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3648036.html
Copyright © 2020-2023  润新知