事务
基本概念:一组要么同时执行成功,要么同时执行失败的SQL语句。是数据库操作的一个执行单元
- 事务开始于:
连接到数据库上,并执行了一条DML语句(insert update delete)
前一个事务结束后,有输入了另一条DML语句 - 事物结束于:
执行commit或rollback语句
执行一条DDL语句,例如:create table语句;在这种情况下,会自动执行commit语句
执行一条DCL语句,例如:grant语句;在这种情况下,会自动执行commit语句
断开与数据库的连接
执行了一条DML语句,该语句却失败了;在这种情况中,会为这个无效的DML语句执行rollback语句
事务的四大特点(ACID)
- 原子性(atomicity)
表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败 - 一致性(consistency)
表示一个事务内有一个操作失败时,所有的更改过的数据都必须去回滚到修改前的状态 - 隔离性(isolation)
事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据 - 持久性(durability)
持久性事务完成之后,它对系统的影响是永久性的
事务隔离级别从低到高:(了解即可)
- 读取未提交
- 读取已提交
- 可重复读
- 序列化
注:一般是读取已提交,越往前效率越高
事务的示例:
package com.first.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 测试事务的基本概念和用法
*/
public class Demo05 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps1 = null;
PreparedStatement ps2 = null;
try {
//加载驱动类
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","root");
conn.setAutoCommit(false); //JDBC中默认是true,自动提交事务
ps1 = conn.prepareStatement("insert into t_user (username,pwd) values (?,?)");
ps1.setObject(1, "代红3");
ps1.setObject(2, "111");
ps1.execute();
System.out.println("插入代红3");
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//第二条语句报错,且两条语句在同一个事务中。同时失败了
ps2 = conn.prepareStatement("insert into t_user (username,pwd) values (?,?,?)");
ps2.setObject(1, "代红4");
ps2.setObject(2, "222");
ps2.execute();
System.out.println("插入代红4");
conn.commit();
} catch (ClassNotFoundException e) {
e.printStackTrace();
try {
conn.rollback(); //回滚
} catch (SQLException e1) {
e1.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
if(ps1!=null){
ps1.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}