简介:
进行事务操作主要是使用Connection中的方法:
开启事务:public void setAutoCommit(boolean autoCommit) throws SQLException
true:自动提交,也就是没执行一条SQL语句都是单独的事务
false:手动提交,就相当于开启事务并在提交前都处于事务的状态中
提交事务:public void commit() throws SQLException
回滚事务:public void rollback() throws SQLException
处理事务的代码格式:
try {
conn.setAutoCommit(false); // 开启事务
// 执行SQL语句
// 执行SQL语句
// 执行SQL语句
// 执行SQL语句
conn.commit(); // 提交事务
}catch() {
conn.rollback(); // 回滚事务
}
这样操作的话,在执行SQL语句的时候如果出现了异常,那么就马上会跳转到rollback()回滚方法,从而保证异常不会影响数据库中的数据。
同一事务中所有的操作都是一个Connection对象进行的
首先在MySQL中创建一个account表并插入几个值:
然后是Dao层的数据库连接操作代码:
package logic;
import java.sql.Connection;
import java.sql.SQLException;
import org.junit.jupiter.api.Test;
import JDBC.JdbcUtils;
import dao.UpdataDao;
public class TransferDemo {
public void transfer(String from, String to, double money) {
// 获取SQL对象
Connection conn = null;
try {
conn = JdbcUtils.getConnection();
// 开启事务
conn.setAutoCommit(false);
// 转账
UpdataDao upd = new UpdataDao();
upd.upDate(conn, from, -money); // 减去money
upd.upDate(conn, to, money); // 加上money
//提交事务
conn.commit();
// 关闭资源
conn.close();
}catch(Exception e) {
try {
// 回滚事务
conn.rollback();
conn.close(); // 关闭资源
} catch (SQLException e1) {
throw new RuntimeException(e1);
}
}
}
}
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class UpdataDao {
/**
* 操作数据库中的数据
* @param conn SQL对象
* @param name 要操作对象的名字
* @param money 加减的金额
*/
public void upDate(Connection conn, String name, double money) {
try {
// SQL模板
String sql = "UPDATE account SET balance=balance+? WHERE name=?"; // 这个是更新数据的模板
String sqlStmt = "SELECT name FROM account"; // 这个检索名称的模板
// 绑定模板
PreparedStatement pstmt = conn.prepareStatement(sql);
Statement stmt = conn.createStatement();
// 获取数据表
ResultSet rs = stmt.executeQuery(sqlStmt);
while(rs.next()) {// 移动光标
if(rs.getString("name").equals(name)) { // 判断当前光标获取的名字是否正确
System.out.println("找到你啦!!");
pstmt.setDouble(1, money);
pstmt.setString(2, name);
// 执行
pstmt.executeUpdate();
break;
}
}
// 没有这个名称则抛出异常
if(rs.isAfterLast()) { // 光标已经在最后了
System.out.println("没有找到!!");
throw new RuntimeException("名称不存在!!!");
}
stmt.close(); // stmt只在本方法中被使用,所以可以在使用后关闭
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}
然后是JSP前端页面代码:
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>title</title>
</head>
<body>
<div align="center">
<form action="<c:url value='/AServlet'/>" method="post">
转账人:<input type="text" name="from"/><br/><br/>
收款人:<input type="text" name="to"/><br/><br/>
转账金额:<input type="text" name="money" size="18px"/><br/><br/>
<input type="submit" value="提交"/><br/>
</form>
</div>
</body>
</html>
最后是Servlet处理请求:
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import logic.TransferDemo;
@WebServlet("/AServlet")
public class AServlet extends HttpServlet {
private static final long serialVersionUID = 9081505028320745516L;
private logic.TransferDemo tf = new TransferDemo();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 获取参数
String from = request.getParameter("from");
String to = request.getParameter("to");
double money = Double.parseDouble(request.getParameter("money"));
this.tf.transfer(from, to, money); // 调用方法来设置参数
response.getWriter().print("从 " + from + " 转账 " + money +" 到 " + to + " 的账户上");
}
}
启动服务器,输入参数:
这里我分别输入了不存在的转账人、不存在的收款人和转账人、收款人 同时不存在的三种参数,查看结果:
数据库中的数据没有变化,说明进行了事务的回滚操作,那么再进行正确参数的输入:
再次查看:
这次执行后数据库进行了一加一减的数据变化,说明转账操作成功。
标签:
JDBC
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)