事务

1.什么是事务:
  当某一功能或逻辑涉及到多个sql语句(DML),此时,我们要
  保证,要么都执行,要么都不执行。这种情况就是一个事务。
2.事务的特点:
  原子性:这个事务要做就做完,要么不做。
  一致性:做之前,保证数据一致;做之后,也要保证数据的一致。
  隔离性:事务并发时,要对事务进行隔离。
  持久性:最好数据要持久保存到数据中。

3. 提交
    JDBC对事务的支持,默认都是执行完sql语句自动提交到数据库,不会回滚,
  如果一个事务涉及到多个sql时,取消自动(自动提交),最好设置成手动提交,中间出现异常时,我们可以回滚。
  事务完成后,要保持数据的持久性,需要手动提交。
  例如: conn.setAutoCommit(true);默认的话为自动提交,
    每执行一个update ,delete或者insert的时候都会自动提交到数据库,无法回滚事务。
    设置conn.setautocommit(false); 只有程序调用
    conn.commit()的时候才会将先前执行的语句一起提交到数据库,这样就实现了数据库的事务。
    保持了数据的持久性。
4.经典案例:银行转账

   

1.
  2 public class DBUtil2 {
  3     private static String driver;
  4     private static String url;
  5     private static String user;
  6     private static String pwd;
  7     /**读取配置文件,只需要加载一次*/
  8     static {
  9         try {//从db文件读取出来内容
 10             /*文件字符流:默认当前文件路径在工程名下。
 11              * :通过当前类的类加载器所获取的流读取配置文件
 12              */
 13             FileReader fr=new FileReader("db.properties");
 14             Properties prop=new Properties();
 15             prop.load(fr);
 16             driver=prop.getProperty("driver");
 17             url=prop.getProperty("url");
 18             user=prop.getProperty("user");
 19             pwd=prop.getProperty("pwd");
 20             Class.forName(driver);//1加载驱动

 21         } catch (Exception e) {
 22             e.printStackTrace();
 23             /*db.properties文件内容:
 24                     driver=oracle.jdbc.driver.OracleDriver
 25                     #driver=oracle.jdbc.OracleDriver
 26                     url=jdbc:oracle:thin:@localhost:1521:orcl
 27                     user=scott
 28                     pwd=1234
 29              */
 30         }
 31     }
 32     
 33     public static  Connection getconn() {//2.建立连接
 34         Connection conn=null;
 35         try {
 36             conn = DriverManager.getConnection( 
 37                     url, user, pwd);
 38              
 39         } catch (Exception e) {
 40             e.printStackTrace();
 41         }
 42         return conn;
 43     }
 44     public static void colseconn(Connection conn) {
 45         try {
 46             if(conn!=null) {
 47                 conn.close();
 48             }
 49         } catch (Exception e) {
 50             e.printStackTrace();
 51         }
 52     }
 53     public static void main(String[] args) {
 54         System.out.println(getconn());//返回连接对象
 55     }
 56 }
 57 2.
 58 public class BankTest {
 59     //账户转账
 60     public static void main(String[] args) {
 61         String account="za1001";
 62         String toAccount="ls1002";
 63         double money=100;
 64      Map<String,String> map =
 65             moneyToMoney(account,toAccount,money);
 66     if(map.containsKey("ok")){
 67         System.out.println(map.get("ok"));
 68     }else{
 69         System.out.println(map.get("fail"));
 70     }
 71 }
 72     
 73     
 74     public static Map<String,String> moneyToMoney(String account,
 75             String toAccount,double money){
 76         Connection conn=null;
 77         Map<String,String> map=null;
 78         try {
 79             conn=DBUtil2.getconn();
 80             map = new HashMap<String,String>();
 81             //取消自动提交
 82              conn.setAutoCommit(false);
 83             
 84             String sql="select * from bank_money where account=?";
 85             PreparedStatement ps=conn.prepareStatement(sql);
 86             ps.setString(1, account);
 87             ResultSet rs=ps.executeQuery();
 88             if(!rs.next()) {
 89                 map.put("fail", "转出账户不存在");
 90                 return map;
 91             }
 92             double mo1=rs.getDouble("money");//转出账户的余额;
 93             //转入账户是否存在,又给?设值
 94             ps.setString(1, toAccount);
 95             rs=ps.executeQuery();
 96             if(!rs.next()) {
 97                 map.put("fail", "转入账户不存在");
 98                 return map;
 99             }
100             double mo2=rs.getDouble("money");
101             if(money>mo1) {
102                 map.put("fail", "余额不足,不能转出");
103                 return map;
104             }
105             sql="update bank_money set money=? where account=?";
106             ps=conn.prepareStatement(sql);
107             //转出账户
108             ps.setDouble(1, mo1-money);//转出账户转账
109             ps.setString(2, account);
110             int c1=ps.executeUpdate();
111             
112             //转入账户修改money
113             ps.setDouble(1, mo2+money);
114             ps.setString(2, toAccount);
115             int c2=ps.executeUpdate();
116             
117             if(c1!=1||c2!=1) {
118                 map.put("fail", "交易失败");
119             }
120             map.put("ok", "交易成功");
121             
122              conn.commit();
123         } catch (Exception e) {
124             e.printStackTrace();
125             //回滚
126             try {
127                 conn.rollback();
128             } catch (SQLException e1) {
129                 e1.printStackTrace();
130             }
131         }finally {
132             DBUtil2.colseconn(conn);
133         }
134         return map;
135     }
136  
137 }
138
3.数据库语句
create table bank_money(
id number primary key,
account varchar2(50) not null,
pwd varchar2(50) not null,
money number(10,2)
);
insert into bank_money values(1,'za1001','123456',10000);
insert into bank_money values(2,'ls1002','654321',5000);
                                            

 

posted @ 2018-03-26 18:11  小鹿笔记  阅读(140)  评论(0编辑  收藏  举报