事务可以理解为:事情要直接完成,不能半途而废!
原理如下:
jdbc程序->事务系统->数据表
提交(commit)
在jdbc程序对数据库进行数据的修改时(写操作)时,会将已经修改好的中间数据放进事务区中,等待jdbc程序对事务区进行commit(提交)后,才会对mySQL中的数据进行影响。(可理解为需要审批,要通行证,出入证之类的),当事务区中的数据提交完成后,事务区会被清空。等待下次的操作。
举例:A借给B100元,在jdbc程序->事务系统中就有两个步骤:A的余额-100(第一个写操作),B的余额+100(第二个写操作)。程序进行到这一步,两个写操作在事务区中接收到了jdbc程序的提交操作后,才会完成数据的修改。
回滚(rockback)
假设上面的事务区中已经存在了中间数据,一旦接收到rockback命令,事务区中的所有数据将会被清空,无论已经存在了多少条中间数据。
举例上面数据传输过程的第二个写操作出现问题,B+100时程序报错,应用程序向事务区发送rockback指令,A-100这条已经成功在事务区中存在的中间数据进行清除,无论之前在事务区内完成了多少条写操作,都会被清空。
使用DbUtils配置文件进行数据库连接:
public class DbUtils {
//数据库工具类,对指定功能进行封装
/**
* 创建新的数据库连接
* @return 新的Connection对象
* @throws SQLException
* @throws ClassNotFoundException
*/
public static Connection getConnection() throws SQLException, ClassNotFoundException {
//1. 加载并注册JDBC驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 创建数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:5001/imooc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true", "root", "root");
return conn;
}
/**
* 关闭连接,释放资源
* @param rs 结果集对象
* @param stmt Statement对象
* @param conn Connection对象
*/
public static void closeConnection(ResultSet rs , Statement stmt , Connection conn){
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(stmt != null){
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn != null && !conn.isClosed() ) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
调用连接进行相关操作:
package harpp.TS;
import common.DbUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TeansactionSample {
public static void main(String[] args) {
Connection conn = null;//jdbc连接数据库的对象
PreparedStatement pstmt = null;//参数化mysql语句的对象
try {
conn = DbUtils.getConnection();//调用封装好
conn.setAutoCommit(false);//关闭自动提交,使用手动来理解提交和回滚机制
String sql = "insert into employee(eno,ename,salary,dname) values(?,?,?,?)";
for(int i=2000;i<3000;i++){
if(i==2005){
// throw new RuntimeException("插入失败!!");
// 此处抛出异常是为了调试提交和回滚命令
}
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1,i);
pstmt.setString(2,"员工"+i);
pstmt.setFloat(3,4000f);
pstmt.setString(4,"研发部");
pstmt.executeUpdate();
}
conn.commit();//for循环结束之后自动提交数据
} catch (Exception e){
e.printStackTrace();
try {
if(conn !=null&& !conn.isClosed()) { //当Connection对象不为空时才执行数据的回滚
conn.rollback();//数据回滚方法
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}finally {
DbUtils.closeConnection(null,pstmt,conn);
}
}
}