JDBC中进行MySQL的事务处理操作(模拟转账操作)

简介:

进行事务操作主要是使用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 +  的账户上);     }  }

启动服务器,输入参数:

 

这里我分别输入了不存在的转账人、不存在的收款人和转账人、收款人 同时不存在的三种参数,查看结果:

 

数据库中的数据没有变化,说明进行了事务的回滚操作,那么再进行正确参数的输入:

再次查看:

这次执行后数据库进行了一加一减的数据变化,说明转账操作成功。