package com.bjpowernode.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * 对事务的处理 * 模拟银行账户转账的操作,A账户向B账户转账10000元,需要从A账户减去10000元,向B账户加入10000元。 * 以上的操作必须同时成功,或者同时失败。 * * 转账需要执行两条update语句 * * 在JDBC中默认情况下支持自动提交(只要执行一条DML语句就自动提交一次) * * 在实际开发中必须将JDBC自动提交机制关闭掉,改成手动提交。 当一个完整的事务结束之后,再手动提交 * * conn.setAutoCommit(false);//关闭自动提交机制 * conn.commit();手动提交,事务结束。 * conn.rollback();手动回滚。 */ public class 关于事务 { public static void main(String[] args) { Connection conn = null; PreparedStatement ps = null; try { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //连接数据库 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","******"); //开启事务:将自动提交机制关闭掉 conn.setAutoCommit(false); //获取预编译的数据库操作对象 String sql = "update act set balance = ? where actno = ?"; ps = conn.prepareStatement(sql); //传值 ps.setDouble(1,10000); ps.setString(2,"A"); //执行SQL语句 int count = ps.executeUpdate(); //再传值 ps.setDouble(1,10000); ps.setString(2,"B"); //执行SQL语句 count += ps.executeUpdate(); System.out.println(count == 2 ? "转账成功" : "转账失败"); //程序运行到此处,说明上面的代码没有出现异常,表示都成功执行了,此时手动提交事务 conn.commit(); } catch (ClassNotFoundException e) { //如果出现异常,为了保险起见,这里需要回滚! try { if (conn != null) { conn.rollback();//手动回滚 } } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally { if (ps != null) { try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
需要在数据库中准备一张账户信息表,其建表语句如下:
drop table if exists act; create table act( actno char(1) primary key, balance double(10,2) #10是有效数字的个数,2是小数位的个数 ); insert into act(actno, balance) VALUES ('A',20000); insert into act(actno, balance) values ('B',0); select * from act;