事务的概念 : 一组要么同时执行成功,要么同时执行失败的SQL语句,是数据库操作一个执行单元
- 事务的四大特性: *
*1.原子性:事务是应用中最小的执行单元
*2.一致性:事务的执行结果,必须使数据库从一个一致性的状态,变成另一个一致性的状态。如果中途有一个出错 则会整体失败 将回滚值最初未执行的状态
*3.隔离型:各个事务互不干扰 任意一个事务的内部操作不会对其他并发的事务都是隔离的 也就是说 并发执行的事务之间不能看到对方的中间状态
*4.持续性:也称持久性:是指 事务一旦提交 对数据的所有改变 都是永久的 通常就是保存进物理数据库中
JDBC中默认自动提交事务 一旦事务失败 则会执行回滚操作
可以通过 connection.setAutoCommit(false); ————–修改关闭自动提交
connection.commit; —————手动提交事务
下面事例一个事务失败回滚的操作
以 testjdbc数据库的t_test表 做例子 先清空表数据
事例正确的操作:
public class Affairs {
private String driver;
private String url;
private String user;
private String password;
public void initParam(String paramFile) {
Properties prop = new Properties();
try {
prop.load(new FileInputStream(paramFile));
} catch (FileNotFoundException e) {
System.out.println("配置文件未找到!");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
driver = prop.getProperty("driver");
url = prop.getProperty("url");
user = prop.getProperty("user");
password = prop.getProperty("password");
}
public void test() throws SQLException {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
System.out.println("没有找到你所调用的类");
e.printStackTrace();
}
Connection connect = null;
PreparedStatement pstmt = null;
PreparedStatement pstmt2 = null;
try {
// 第一次执行
try {
connect = DriverManager.getConnection(url, user, password);
} catch (SQLException e1) {
System.out.println("连接数据库失败");
e1.printStackTrace();
}
try {
connect.setAutoCommit(false);// 修改关闭自动提交
} catch (SQLException e1) {
System.out.println("关闭自动提交失败");
e1.printStackTrace();
} // 关闭事务自动提交 JDBC默认自动提交 true
try {
pstmt = connect.prepareStatement("insert into t_test(username,pwd)
values (?,?)");
} catch (SQLException e1) {
System.out.println("执行SQL语句失败");
e1.printStackTrace();
}
// 插入第一个正确的数据
pstmt.setObject(1, "叶良辰");
pstmt.setObject(2, "666");
pstmt.execute();
System.out.println("插入第一个记录!");
// 使用线程休息5S
try {
System.out.println("------------------CPU休息5S:-----------------------------");
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
pstmt2 = connect.prepareStatement("insert into t_test (username,pwd)
values (?,?)");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 插入第一个错误的数据
pstmt2.setObject(1, "赵日天");
pstmt2.setObject(2, "556");
pstmt2.execute();
System.out.println("插入第二个记录!");
try {
connect.commit();
System.out.println("插入数据失败! 即将回滚至初始状态");
connect.rollback();
e.printStackTrace();
} // 提交数据
} finally {
if (pstmt2 != null) {
try {
pstmt2.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connect != null) {
try {
connect.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args)
throws FileNotFoundException, IOException, ClassNotFoundException, SQLException {
Affairs af = new Affairs();
af.initParam("E:/javaiotest/mysql.ini");
af.test();
}
}
表内已经正确添加数据:
将代码第二次添加的语句 弄错
pstmt2 = connect.prepareStatement("insert into t_test (username,pwd) values (?,?,?)");
第一个插入正确的 第二个是错误的 事务需要一组数据都成功才算成功 否则失败 回滚 未执行之前的状态
第二条记录插入失败 :