数据库事务
1)在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。
2)为确保数据库中数据的一致性,数据的操纵应该是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态
3)事务的操作:先定义开始一个事务,然后对数据做修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃所做的所有修改而回到开始事务时的状态。
4)事务的ACID(acid)属性
原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态
隔离性:事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对兵法的其他事务是隔离的,并发执行的各个事务之间不能互相干扰
持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
JDBC 事务处理
1)事务:指构成单个逻辑工作单元的操作集合
2)事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态
3)当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚
4)为了让多个SQL语句作为一个事务执行:
- 调用Connection对象的setAutoCommit(false);以取消自动提交事务
- 在所有的SQL语句都成功执行后,调用commit()方法提交事务
- 在出现异常时,调用rollback()方法回滚事务
举个例子
public class JDBCTest04 {
/**
* 违反事务一致性
* A 给 B 汇款 500 元
*/
public void testTransaction() throws SQLException, ClassNotFoundException {
String driverClass = "com.mysql.jdbc.Driver";
String jdbcurl = "";
Connection connection = null;
Class.forName(driverClass);
connection = DriverManager.getConnection(jdbcurl,"user","password");
PreparedStatement preparedStatement = null;
String sql = "UPDATE users SET balance = " + "balance - 500 WHERE id = 1"; // A 账号 - 500
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
int i = 10 / 0; // 第一条sql执行完成A账号-500后,执行到这里报错导致第二条sql没有执行,从而违反了数据的一致性
System.out.println(i);
sql = "UPDATE users SET balance = " + "balance + 500 WHERE id = 2";// B 账号 + 500
connection = DriverManager.getConnection(jdbcurl,"user","password");
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
}
}
复制
public class JDBCTest04 {
/**
* 保证事务一致性
* A 给 B 汇款 500 元
* 1. 如果多个操作,每个操作使用的是自己的单独的连接,则无法保证事务
* 2. 具体步骤:
* 1)事务操作开始前,开始事务:取消connection的默认提交行为
* connection.setAutoCommit(false)
* 2)如果事务的操作都成功,则提交:connection.commit();
* 3)回滚事务:若出现异常,则在catch块中回滚事务
*/
public void testTransaction01() throws SQLException {
String driverClass = "com.mysql.jdbc.Driver";
String jdbcurl = "";
PreparedStatement preparedStatement = null;
Connection connection = null;
try {
Class.forName(driverClass);
connection = DriverManager.getConnection(jdbcurl,"user","password");
connection.setAutoCommit(false);
String sql = "UPDATE users SET balance = " + "balance - 500 WHERE id = 1";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
int i = 10 / 0;
sql = "UPDATE users SET balance = " + "balance + 500 WHERE id = 2";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
connection.commit();
}catch (Exception e){
e.printStackTrace();
try {
connection.rollback();
}catch (Exception e1){
e.printStackTrace();
}
}finally {
preparedStatement.close();
connection.close();
}
}
}
复制