zoukankan      html  css  js  c++  java
  • 编程式事务

     事务(Transaction)
      分为编程式事务和声明式事务,此处说明的是编程时事务:
                
            演示银行转账的功能(以此为例):
              1.创建一张表示账号的表
                    CREATE TABLE t_account(
                        id INT PRIMARY KEY AUTO_INCREMENT,
                        a_name VARCHAR(50),
                        balance DECIMAL(11,2)//11表示一共有几位,2表示有几位小数
                    )
                    
              2.向表中插入几个用户
                    INSERT INTO t_account(id,a_name,balance) VALUES(NULL,'sunwukong',1000);
                    INSERT INTO t_account(id,a_name,balance) VALUES(NULL,'zhubajie',1000);
                    INSERT INTO t_account(id,a_name,balance) VALUES(NULL,'shaheshang',1000);
                    SELECT * FROM t_account;        
                  
              3.#sunwukong向shaheshang转账100元      
                    #从sunwukong的账号减去100元
                    UPDATE t_account SET balance = balance - 100 WHERE a_name='sunwukong';

                    #给shaheshang的账号加上100元
                    UPDATE t_account SET balance = balance +100 WHERE a_name = 'shaheshang';
                       
                 重新设置为1000元:
                    UPDATE t_account SET balance =1000;
                    
              4.从java代码中演示上面的案例:
                 1.创建Dao类            

      
     1  public class AcountDao {    
     2                     public void update(String name,double money){
     3                         //准备两个变量
     4                         Connection conn = null;
     5                         PreparedStatement ps = null;
     6                         //准备SQL模板
     7                         String sql = "UPDATE t_account SET balance = balance + ? WHERE a_name = ?";
     8                         
     9                         try {
    10                             conn = JDBCUtil.getConnection();
    11                             //获取PreparedStatement
    12                             ps = conn.prepareStatement(sql);
    13                             //填充占位符
    14                             ps.setDouble(1, money);
    15                             ps.setString(2, name);
    16                             
    17                             //执行SQL语句
    18                             ps.executeUpdate();
    19                             
    20                         } catch (SQLException e) {
    21                             // TODO Auto-generated catch block
    22                             e.printStackTrace();
    23                         }finally{
    24                             JDBCUtil.close(conn, ps, null);
    25                         }
    26                     }
    27                 }
    Dao中进行数据库操作             

                2.测试该DAO              

             public class TestTransaction {
                        private AcountDao accountDao = new AcountDao();
                        
                        @Test
                        public void test() {
                            //从sunwukong账户向shaheshang账户转账100元!
                            //1.从sunwukong账户扣除100元
                            accountDao.update("sunwukong", -100);
                            //2.向shaheshang账户添加100元
                            accountDao.update("shaheshang", 100);
                        }
                    }

                    //显然上面是可以正常执行的!
                    但是如果上面的程序在suwukong减去100元之后,shaheshang加钱之前,出现了异常,如下所示:                    

                  //从sunwukong账户向shaheshang账户转账100元!
                            //1.从sunwukong账户扣除100元
                            accountDao.update("sunwukong", -100);
                            int i  =10/0;//添加一个异常
                            //2.向shaheshang账户添加100元
                            accountDao.update("shaheshang", 100);            

            - 在开发中我们的一个业务往往需要同时操作多个表,这些操作往往是不可分割,业务中的对数据库的多次操作,
              要么同时成功,要么全都失败。
           
            - 事务的特性(ACID):
                原子性(atomicity)
                    一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
                    
                一致性(consistency)
                    事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

                隔离性(isolation)
                    一个事务的执行不能被其他事务干扰。
                        即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
                        
                持久性(durability)
                    持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
                        接下来的其他操作或故障不应该对其有任何影响。
                        
            - 操作事务的基本步骤:
                1.开启事务
                    - 开启事务以后,我们只后的所有操作将都会在同一个事务当中
                2.操作数据库
                    - 开启事务以后再去操作数据库,所有操作将不会直接提交到数据库中
                3.提交事务
                    - 将修改应用到数据库
                4.回滚事务
                    - 数据库操作过程中出现异常了,回滚事务,回滚事务以后,数据库变成开启事务之前的状态
            
            - mysql中的事务控制
                #开启事务
                    START TRANSACTION
                #回滚事务
                    ROLLBACK            
                #提交事务
                    COMMIT
                
            - JDBC中的事务主要通过Connection对象来控制的
                1.开启事务
                    void setAutoCommit(boolean autoCommit) throws SQLException;
                    - 设置事务是否自动提交,默认是自动提交
                    - 设置事务手动提交
                        conn.setAutoCommit(false);
                    
                2.提交事务
                    void commit() throws SQLException;
                    - 提交事务
                    conn.commit()
                
                3.回滚事务
                    void rollback() throws SQLException;
                    - 回滚事务
                    conn.rollback()
                    
            - 事务控制的格式:         

     1 ·      //创建一个Connection
     2             Connection conn = null;
     3             
     4             try{
     5                 
     6                 //获取Connection
     7                 conn = JDBCUtils.getConnection();
     8                 
     9                 //开启事务
    10                 conn.setAutoCommit(false);
    11                 
    12                 //对数据库进行操作
    13                 
    14                 //操作成功,提交事务
    15                 conn.commit();
    16                 
    17             }catch(Exception e){
    18                 e.printStackTrace();
    19                 
    20                 //回滚事务
    21                 try {
    22                     conn.rollback();
    23                 } catch (SQLException e1) {
    24                     e1.printStackTrace();
    25                 }
    26                 
    27             }finally{
    28                 JDBCUtils.close(conn, null, null);
    29             }   

        - 注意:我们在同一个事务中使用的数据库连接(Connection)必须是同一个,否则事务还是不作用!    
            所以此时原来的AcountDAO中的update方法要改为如下所示:        

      
     1 public class AcountDao {    
     2                 public void update(Connection conn,String name,double money){
     3                     //准备两个变量
     4                     PreparedStatement ps = null;
     5                     //准备SQL模板
     6                     String sql = "UPDATE t_account SET balance = balance + ? WHERE a_name = ?";
     7                     
     8                     try {
     9                         //获取PreparedStatement
    10                         ps = conn.prepareStatement(sql);
    11                         //填充占位符
    12                         ps.setDouble(1, money);
    13                         ps.setString(2, name);
    14                         
    15                         //执行SQL语句
    16                         ps.executeUpdate();
    17                         
    18                     } catch (SQLException e) {
    19                         // TODO Auto-generated catch block
    20                         e.printStackTrace();
    21                     }finally{
    22                         //此时也不能在这里关闭数据库连接了,而是在外边统一关闭
    23                         JDBCUtil.close(null, ps, null);
    24                     }
    25                 }
    26             }
    Dao类中更改后代码
      
     1 @Test
     2     public void test() {
     3         Account account=new Account();
     4         
     5         Connection conn = JDBCUtil.getConnection();
     6         try {
     7             conn.setAutoCommit(false);
     8             account.update(conn,"孙悟空", -100);
     9             int i=10/0;
    10             account.update(conn,"猪八戒", 100);
    11             conn.commit();
    12         } catch (SQLException e) {
    13             try {
    14                 conn.rollback();//fa
    15             } catch (SQLException e1) {
    16                 // TODO Auto-generated catch block
    17                 e1.printStackTrace();
    18             }
    19         }
    20         if(conn!=null){
    21             try {
    22                 conn.close();
    23             } catch (SQLException e) {
    24                 // TODO Auto-generated catch block
    25                 e.printStackTrace();
    26             }
    27         }    
    28     }
    更改后测试类代码
  • 相关阅读:
    4-6 随机数
    linux下安装jdk
    markdown使用教程
    IDE新建gradle各种坑
    day05泛型类和泛型方法
    day05集合
    day15 Ui自动化中三种等待方式
    day15 Ui自动化元素的定位
    Windows系统
    解决sublime text 3使用Install Package时出现There are no packages available for installation问题
  • 原文地址:https://www.cnblogs.com/kangxingyue-210/p/7456412.html
Copyright © 2011-2022 走看看