news 2026/7/5 21:06:05

JavaWeb-JDBC事务回滚

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaWeb-JDBC事务回滚

什么是JDBC?

Java连接数据库!

需要jar包支持:

  • java.sql
  • javax.sql
  • mysql-connter-java……连接驱动(必须要导入)

实验-Mysql数据库

MySQL数据插入表中数据

CREATETABLEusers(`id`INTPRIMARYKEY,`name`VARCHAR(40),`password`VARCHAR(40),`email`VARCHAR(2222),`birthday`DATE);INSERTINTOusers(`id`,`name`,`password`,`email`,`birthday`)VALUES(1,'admin','123456','admin@gmail.com','1998-06-18');INSERTINTOusers(`id`,`name`,`password`,`email`,`birthday`)VALUES(2,'system','000000','system@gmail.com','1999-06-18');INSERTINTOusers(`id`,`name`,`password`,`email`,`birthday`)VALUES(3,'sa','00000000','sa@gmail.com','1992-06-18');INSERTINTOusers(`id`,`name`,`password`,`email`,`birthday`)VALUES(4,'web','0123456789','web@gmail.com','1991-06-18');SELECT*FROMusers;

导入数据库依赖

<dependencies><!--MySQL驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency></dependencies>

idea连接数据库

jdbc连接七部曲

  1. 获取配置信息&解决中文乱码
  2. 加载驱动

显式加载:

* Class.forName("..."):这是最经典的方式,在代码中显式地加载驱动类。例如,Class.forName("com.mysql.cj.jdbc.Driver")。 * 优点:兼容老版本,建议写、兼容性强。 * 缺点:需要手动编写代码,在一些情况下(如 JDBC 4.0 之后),可能显得冗余。

隐示加载:

spl模式

* SPI ,全称为 Service Provider Interface,是一种服务发现机制。 * 它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。 * 这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中都使用到了SPI机制。

jdbc4.0后 可以自动扫描jar包下面的这个文件

  1. 连接数据库,代表数据库
  2. 向数据库发送SQL的对象 Statement 用它来做(CRUD)增删改查
  3. 编写SQL
  4. 执行查询SQL语句
  5. 关闭连接,释放资源

增删改查

//受影响的行数,CRUD都是用executeUpdate即可inti=preparedStatement.executeUpdate();

完整代码

publicstaticvoidmain(String[]args)throwsClassNotFoundException,SQLException{//1.获取配置信息// serverTimezone=UTC 解决中文乱码Stringurl="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF-8";Stringuser="root";Stringpassword="123456";// 2.加载驱动// Class.forName("com.mysql.jdbc.Driver");// 3.连接数据库,代表数据库Connectionconnection=DriverManager.getConnection(url,user,password);// 4.向数据库发送SQL的对象,Statement :用它来做(CRUD)增删改查Statementstatement=connection.createStatement();// 5.编写SQLStringsql="select * from users;";// 6.执行查询SQL语句,返回一个ResultSet对象ResultSetresultSet=statement.executeQuery(sql);while(resultSet.next()){// 如果还有数据System.out.println("id="+resultSet.getObject("id"));System.out.println("name="+resultSet.getObject("name"));System.out.println("password="+resultSet.getObject("password"));System.out.println("email="+resultSet.getObject("email"));System.out.println("birthday="+resultSet.getObject("birthday"));}// 7.关闭连接,释放资源(一定要做)先开后关statement.close();connection.close();resultSet.close();}}

预编译SQL

更加安全

publicclassTestJdbc2{publicstaticvoidmain(String[]args)throwsClassNotFoundException,SQLException{// 1.配置信息Stringurl="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF-8";Stringuser="root";Stringpassword="123456";// 2.加载驱动Class.forName("com.mysql.jdbc.Driver");// 3.连接数据库Connectionconnection=DriverManager.getConnection(url,user,password);// 4.编写SQLStringsql="insert into users(`id`,`name`,`email`,`password`,`birthday`) values (?,?,?,?,?);";// 5.预编译PreparedStatementpreparedStatement=connection.prepareStatement(sql);//设置?的值preparedStatement.setInt(1,5);//给第一个占位符,赋值id为5preparedStatement.setString(2,"test");//给第二个占位符,赋值name为testpreparedStatement.setString(3,"test@gmail.com");//给第三个占位符,赋值email为test@gmail.compreparedStatement.setString(4,"123456");//给第四个占位符,赋值password为123456preparedStatement.setDate(5,newDate(newjava.util.Date().getTime()));//给第五个占位符,赋值birthday为当前时间// 5. 执行SQLinti=preparedStatement.executeUpdate();//增删改查的判断if(i>0){System.out.println("插入成功");}else{System.out.println("插入失败");}// 6.关闭连接,释放资源connection.close();preparedStatement.close();}}

事务

要么都成功,要么都失败

ACID原则(原子性、一致性、隔离性、持久性):保证数据的安全。

  • 开启事务
  • 事务提交 commit()
  • 事务回滚 rollback()
  • 关闭事务

转账:

A:1000

B:1000

A(900) --100–>B(1100)

如果服务器崩溃了怎么办?我们不应该让这100块钱凭空的消失

Junit单元测试

测试数据经常使用,不需要new类什么的

导入依赖

pom.xml

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>

publicclassTestJdbc3{@Testpublicvoidtest(){System.out.println("test");}}

添加@Test注解

可以看见运行键不再是灰色了,可以直接输出

@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行!

事务

常用通常有以下:

  • start transaction ;
  • rollback ;
  • commit ;
starttransaction;#开启事务updatejdbc.accountsetmoney=money-100whereid='1';# update jdbc.account set money = money+ 100 where id = '1';rollback;# 回滚事务,如果中间崩溃了怎么样,就会回滚,不进行提交commit;# 提交事务

可以选中这两行执行

就会只执行这两行

回滚

一定要添加这一行,这个引擎支持回滚

ALTERTABLEjdbc.accountENGINE=InnoDB;

案例代码:

publicclassTestJdbc3{@Testpublicvoidtest(){//配置信息Stringurl="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF-8";Stringuser="root";Stringpassword="123456";Connectionconnection=null;try{// 加载驱动Class.forName("com.mysql.jdbc.Driver");// 连接数据库connection=DriverManager.getConnection(url,user,password);// 检查自动提交状态System.out.println("自动提交状态: "+connection.getAutoCommit());// 开启事务connection.setAutoCommit(false);System.out.println("事务已开启");// 执行第一条SQLStringsql="update jdbc.account set money = money - 100 where id = 2;";PreparedStatementpstmt1=connection.prepareStatement(sql);intcount1=pstmt1.executeUpdate();System.out.println("第一条SQL影响行数: "+count1);pstmt1.close();// 检查当前数据状态checkAccountBalance(connection);// 制造错误 - 这会触发回滚inti=1/0;// 执行第二条SQLStringsql1="update jdbc.account set money = money + 100 where id = 3;";PreparedStatementpstmt2=connection.prepareStatement(sql1);intcount2=pstmt2.executeUpdate();System.out.println("第二条SQL影响行数: "+count2);pstmt2.close();// 提交事务connection.commit();System.out.println("事务提交成功!");}catch(Exceptione){System.out.println("捕获到异常: "+e.getMessage());// 发生异常时回滚事务if(connection!=null){try{connection.rollback();System.out.println("事务已回滚!所有操作已撤销");// 回滚后再次检查数据状态checkAccountBalance(connection);}catch(SQLExceptionex){System.out.println("回滚失败: "+ex.getMessage());ex.printStackTrace();}}e.printStackTrace();}finally{// 恢复自动提交并关闭连接if(connection!=null){try{connection.setAutoCommit(true);// 恢复自动提交connection.close();System.out.println("连接已关闭");}catch(SQLExceptione){e.printStackTrace();}}}}// 辅助方法:检查账户余额privatevoidcheckAccountBalance(Connectionconn)throwsSQLException{StringcheckSql="SELECT id, money FROM jdbc.account WHERE id IN (2, 3)";PreparedStatementpstmt=conn.prepareStatement(checkSql);ResultSetrs=pstmt.executeQuery();System.out.println("当前账户余额:");while(rs.next()){System.out.println("账户 "+rs.getInt("id")+": "+rs.getDouble("money"));}rs.close();pstmt.close();}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/4 23:58:38

大数据领域数据产品的娱乐行业应用

大数据领域数据产品的娱乐行业应用关键词&#xff1a;大数据、娱乐行业、数据产品、用户画像、推荐系统、内容分析、预测模型摘要&#xff1a;本文深入探讨大数据技术在娱乐行业的创新应用。我们将从数据采集、处理到应用的全链路分析&#xff0c;重点介绍用户行为分析、内容推…

作者头像 李华
网站建设 2026/7/3 4:16:02

3步搞定虚拟桌宠性能优化:从卡顿到流畅的实战指南

3步搞定虚拟桌宠性能优化&#xff1a;从卡顿到流畅的实战指南 【免费下载链接】VPet 虚拟桌宠模拟器 一个开源的桌宠软件, 可以内置到任何WPF应用程序 项目地址: https://gitcode.com/GitHub_Trending/vp/VPet 你是否遇到过虚拟桌宠触摸响应迟钝、动画卡顿影响用户体验的…

作者头像 李华
网站建设 2026/7/4 20:00:35

9 个降AI率工具推荐,本科生论文查重优化神器

9 个降AI率工具推荐&#xff0c;本科生论文查重优化神器 论文写作的“三座大山”&#xff1a;时间、重复率与降重之痛 对于本科生来说&#xff0c;写论文从来不是一件轻松的事情。从选题到文献综述&#xff0c;再到撰写正文和反复修改&#xff0c;每一个环节都充满了挑战。尤其…

作者头像 李华
网站建设 2026/7/3 2:59:39

10 个降ai率工具推荐,本科生论文AI辅助神器

10 个降ai率工具推荐&#xff0c;本科生论文AI辅助神器 论文写作的困局&#xff1a;时间紧、任务重、降重难 对于大多数本科生来说&#xff0c;毕业论文不仅是一项学术任务&#xff0c;更是一场与时间赛跑的挑战。从选题到开题报告&#xff0c;从文献综述到实证分析&#xff0c…

作者头像 李华
网站建设 2026/7/5 14:02:17

像素艺术打印实战:从数字创作到实体呈现的完整指南

像素艺术打印实战&#xff1a;从数字创作到实体呈现的完整指南 【免费下载链接】piskel A simple web-based tool for Spriting and Pixel art. 项目地址: https://gitcode.com/gh_mirrors/pi/piskel 还记得第一次打印像素画时的失望吗&#xff1f;精心设计的作品在纸上…

作者头像 李华
网站建设 2026/7/4 21:31:37

29、Samba远程服务器管理与域成员服务器配置全解析

Samba远程服务器管理与域成员服务器配置全解析 1. 远程服务器管理概述 Windows 提供了大量远程管理应用程序,如 Server Manager 和 User Manager for Domains 。这些工具能帮助管理员管理文件共享、启停服务、搜索日志文件以及监控系统资源等。支持 Windows 管理员熟悉的工具…

作者头像 李华