数据库事务
- 事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态。
? 一组逻辑操作单元,一个或多个DML操作
- 事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)**到最初状态。
数据一旦提交,就不可回滚
哪些操作会导致数据的自动提交
DDL操作一旦执行,就会自动提交
? > set autocommit = false 对DDL操作失效
DML默认情况下,一旦执行,就会自动提交
? 我们可以通过set autocommit = false 的方式取消DML操作的自动提交
默认在关闭连接时,会自动的提交数据
JDBC程序中为了让多个 SQL 语句作为一个事务执行:**
- 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
- 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
- 在出现异常时,调用 rollback(); 方法回滚事务
若此时 Connection 没有被关闭,还可能被重复使用,则需要恢复其自动提交状态 setAutoCommit(true)。尤其是在使用数据库连接池技术时,执行close()方法前,建议恢复自动提交状态。
@Test
//案例:用户AA向用户BB转账100
public void testUpdateWithTx() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
//取消数据的自动提交功能
conn.setAutoCommit(false);
String sql1 = "update user_table set balance = balance - 100 where user = ?";
update(conn,sql1,"AA");
String sql2 = "update user_table set balance = balance + 100 where user = ?";
update(conn,sql1,"BB");
System.out.println("转账成功");
//提交数据
conn.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//回滚数据
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally {
JDBCUtils.closeResource(conn, null);
}
}
//通用的增删改操作---version2.0 (考虑上事务)
public int update(Connection conn,String sql,Object...args) {
PreparedStatement ps = null;
try {
conn = JDBCUtils.getConnection();
//1.预编译sql语句:返回PreparedStatement的实例
ps = conn.prepareStatement(sql);
//2.填充占位符
for(int i = 0;i < args.length;i++) {
ps.setObject(i + 1, args[i]);
}
//3.执行
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//修改其为自动提交数据
//主要针对于数据连接池的使用
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//4.资源关闭
JDBCUtils.closeResource(null, ps);
}
return 0;
}