JDBC 事务处理【最终版】

事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态。
事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。
当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。
为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。 

当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚

JDBC 事务处理
    为了让多个 SQL 语句作为一个事务执行:
  • 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
  • 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
  • 在出现异常时,调用 rollback(); 方法回滚事务
  • 若此时 Connection 没有被关闭, 则需要恢复其自动提交状态

// AA  用户转给  BB  用户  100 元。  1.AA  用户   扣除  100 2.BB 用户增加  100
@Test
      public   void  testUpdate2  ()   {
        Connection conn  =   null  ;
          try   {
            conn  =  JDBCUtils  . getConnection  ();
              // 1.  开启事务
            conn  . setAutoCommit  (  false );
            String sql1  =   "update user_table set balance = balance - ? where user = ?" ;
            updateWithTx  ( conn  ,  sql1  ,   100  ,   "AA" );

              //  模拟网络异常
              // System.out.println(10 / 0);

            String sql2  =   "update user_table set balance = balance + ? where user = ?" ;
            updateWithTx  ( conn  ,  sql2  ,   100  ,   "BB" );
              // 2.  提交事务
            conn  . commit  ();
          }   catch   ( Exception e  )   {
            e  . printStackTrace  ();
              if   ( conn  !=   null  )   {
                  try   {
                      // 3.  回滚事务
                    conn  . rollback  ();  // 出现异常则直接会执行  catch  中的内容,然后使之前对数据库的操作回滚
                  }   catch   ( SQLException e1  )   {
                    e1  . printStackTrace  ();
                  }
              }
          }   finally   {
            JDBCUtils  . close  (  null ,  null ,  conn );
          }
      }

      //  通用的增删改方法(  version 3.0   :  考虑上数据库事务
      public   void  updateWithTx  ( Connection conn  ,  String sql  ,  Object ...  args )  {

          // 1.  返回一个 PreparedStatement  的对象,涉及预编译  sql  语句
        PreparedStatement ps  =   null  ;
          try   {
            ps  =  conn  . prepareStatement  ( sql  );
              // 2.  填充占位符
              for   (  int  i  =   0 ;  <  args  . length  ;  i  ++)   {
                ps  . setObject  ( +   1  ,  args  [ i  ]); //  设置占位符
              }
              // 3.  执行
            ps  . executeUpdate  ();
          }   catch   ( Exception e  )   {
            e  . printStackTrace  ();
          }   finally   {
              // 4.  关闭操作
            JDBCUtils  . close  (  null ,  ps  ,   null );  //  注意连接不能关,否则会有语句执行不到
          }
      }


你可能感兴趣的:(JDBC 事务处理【最终版】)