JDBC 事务处理
一、事务的概念
事务处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败,事务本身具有原子性(Atomicity)、一致性(Consistency)、隔离性或独立性(Isolation) 、持久性(Durability)4 个特 性,这 4 个特性也被称为 ACID 特征。
原子性:原子性是事务最小的单元,是不可再分隔的单元,相当于一个个小的数据库操作,这些操作必须同时 成功,如果一个失败了,则一切的操作将全部失败。
一致性:指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效 性,如果事务出现了错误,则回到最原始状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一 致状态。
隔离性:多个事务可以同时进行且彼此之间无法访问,只有当事务完成最终操作时,才可以看到结果。
持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
1、就算李四没有接收到钱,张三的钱也有可能转出
1 /** 2 * 转出 3 * @param con 4 * @param accountName 5 * @param account 6 * @throws Exception 7 */ 8 private static void outCount(Connection con, 9 String accountName,int account)throws Exception{ 10 String sql="update t_account set accountBalance=accountBalance-? " 11 + "where accountName=?"; 12 PreparedStatement pstmt=con.prepareStatement(sql); 13 pstmt.setInt(1, account); 14 pstmt.setString(2, accountName); 15 pstmt.executeUpdate(); 16 } 17 /** 18 * 转入 19 * @param con 20 * @param accountName 21 * @param account 22 * @throws Exception 23 */ 24 private static void inCount(Connection con, 25 String accountName,int account)throws Exception{ 26 String sql="update t_account set accountBalance=accountBalance+? " 27 + "where accountName=?"; 28 PreparedStatement pstmt=con.prepareStatement(sql); 29 pstmt.setInt(1, account); 30 pstmt.setString(2, accountName); 31 pstmt.executeUpdate(); 32 } 33 34 public static void main(String[] args) { 35 Connection con=null; 36 try { 37 con=dbUtil.getCon(); 38 con.setAutoCommit(false);//取消自动提交 39 System.out.println("张三向李四转账!"); 40 int account=500; 41 outCount(con, "张三", account); 42 inCount(con, "李四", account); 43 System.out.println("转账成功!"); 44 } catch (Exception e) { 45 try { 46 con.rollback(); 47 } catch (SQLException e1) { 48 e1.printStackTrace(); 49 } 50 e.printStackTrace(); 51 }finally { 52 try { 53 con.commit(); 54 con.close(); 55 } catch (SQLException e) { 56 e.printStackTrace(); 57 } 58 } 59 }
1、转入与转出的钱必须一一对应才可执行
1 /** 2 * 转出 3 * @param con 4 * @param accountName 5 * @param account 6 * @throws Exception 7 */ 8 private static void outCount(Connection con, 9 String accountName,int account)throws Exception{ 10 String sql="update t_account set accountBalance=accountBalance-? " 11 + "where accountName=?"; 12 PreparedStatement pstmt=con.prepareStatement(sql); 13 pstmt.setInt(1, account); 14 pstmt.setString(2, accountName); 15 pstmt.executeUpdate(); 16 } 17 /** 18 * 转入 19 * @param con 20 * @param accountName 21 * @param account 22 * @throws Exception 23 */ 24 private static void inCount(Connection con, 25 String accountName,int account)throws Exception{ 26 String sql="update t_account set accountBalance=accountBalance+? " 27 + "where accountName=?"; 28 PreparedStatement pstmt=con.prepareStatement(sql); 29 pstmt.setInt(1, account); 30 pstmt.setString(2, accountName); 31 pstmt.executeUpdate(); 32 } 33 34 public static void main(String[] args) { 35 Connection con=null; 36 Savepoint sp=null; 37 try { 38 con=dbUtil.getCon(); 39 con.setAutoCommit(false);//取消自动提交 40 System.out.println("张三向李四转账!"); 41 int account=500; 42 outCount(con, "张三", account); 43 sp=con.setSavepoint();//设置一个保存点 44 inCount(con, "李四", account); 45 System.out.println("转账成功!"); 46 } catch (Exception e) { 47 try { 48 con.rollback(sp);//回滚到sp保存点 49 } catch (SQLException e1) { 50 e1.printStackTrace(); 51 } 52 e.printStackTrace(); 53 }finally { 54 try { 55 con.commit(); 56 con.close(); 57 } catch (SQLException e) { 58 e.printStackTrace(); 59 } 60 } 61 }