1、创建账户account数据表
create table account(
id int primary key auto_increment,
name varchar(100),
money int
);
insert into account (name,money) values('aaa',1000);
insert into account (name,money) values('bbb',1000);
2、账户aaa给账户bbb转账,模拟出现错误,交易失败的情况。
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();//此链接,默认事务是自动提交的。即一条sql语句就是一个事务。
String sql = "update account set money=money-100 where name='aaa'";
stmt = conn.prepareStatement(sql);
stmt.executeUpdate(sql);
int i = 1/0;//转账过程出现异常,程序终止运行。aaa付钱,然而bbb并没有收到钱。
sql = "update account set money=money+100 where name='bbb'";
conn.prepareStatement(sql);
stmt.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.release(rs, stmt, conn);
}
结果:aaa账户money=900,而bbb账户还是1000。出现错误!!!
3、开启事务
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
conn.setAutoCommit(false);// start transaction 开启事务
String sql = "update account set money=money-100 where name='aaa'";
stmt = conn.prepareStatement(sql);
stmt.executeUpdate(sql);
int i = 1 / 0;// 异常
sql = "update account set money=money+100 where name='bbb'";
conn.prepareStatement(sql);
stmt.executeUpdate(sql);
} catch (Exception e) {
try {
conn.rollback();
} catch (Exception e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
conn.commit();
} catch (SQLException e2) {
e2.printStackTrace();
}
JdbcUtils.release(rs, stmt, conn);
}
结果:因为出现错误,所以自动回滚到 start transaction处。aaa和bbb账户都为1000。结果合理。
4、自己设定回滚点。
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
Savepoint sp = null;//回滚点
try {
conn = JdbcUtils.getConnection();
conn.setAutoCommit(false);// start transaction 开启事务
String sql = "update account set money=money-100 where name='aaa'";
stmt = conn.prepareStatement(sql);
stmt.executeUpdate(sql);
sp = conn.setSavepoint();//设置回滚点
int i = 1 / 0;// 异常
sql = "update account set money=money+100 where name='bbb'";
conn.prepareStatement(sql);
stmt.executeUpdate(sql);
} catch (Exception e) {
try {
conn.rollback(sp);
} catch (Exception e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
conn.commit();
} catch (SQLException e2) {
e2.printStackTrace();
}
JdbcUtils.release(rs, stmt, conn);
}
所以结果是:aaa为900,bbb为1000。