資料庫事務操作之完成銀行轉帳功能,附詳細代碼

轉出賬戶:
轉入賬戶:


轉賬金額:

數據庫事務操作之完成銀行轉賬功能,附詳細代碼


servlet

package com.itheima.transfer.web;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.itheima.transfer.service.TransferService;public class TransferServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//接受轉賬的參數String out = request.getParameter("out");String in = request.getParameter("in");String moneyStr = request.getParameter("money");double money = Double.parseDouble(moneyStr);//調用業務層的轉賬方法TransferService service = new TransferService();boolean isTransferSuccess = service.transfer(out,in,money);response.setContentType("text/html;charset=UTF-8");if(isTransferSuccess){response.getWriter().write("轉賬成功!!!");}else{response.getWriter().write("轉賬失敗!!!");}}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

service

package com.itheima.transfer.service;import java.sql.Connection;import java.sql.SQLException;import com.itheima.transfer.dao.TransferDao;import com.itheima.utils.DataSourceUtils;import com.itheima.utils.MyDataSourceUtils;public class TransferService {public boolean transfer(String out, String in, double money) {TransferDao dao = new TransferDao();boolean isTranferSuccess = true;//標記轉賬是否正確Connection conn = null;try {//開啟事務conn = DataSourceUtils.getConnection();conn.setAutoCommit(false);//開啟事務//轉出錢的方法dao.out(out,money);//轉入錢的方法dao.in(in,money);} catch (Exception e) {isTranferSuccess = false;//轉入錢和轉出錢應該是兩個操作,如果這個操作出問題,會有異常,則 isTranferSuccess 標記為false,標記轉賬失敗//回滾事務try {conn.rollback();//出現異常就要回滾} catch (SQLException e1) {e1.printStackTrace();}e.printStackTrace();} finally{try {conn.commit();最後提交事務} catch (SQLException e) {e.printStackTrace();}}return isTranferSuccess;}}

回滾的理解方式,回滾在數據庫層面可以理解為數據庫操作失效,數據庫沒有變化,而在代碼的理解角度可以看成,回滾是代碼回滾到事務開啟的地方,也就是說從開啟事務開始conn.setAutoCommit(false);,代碼往下執行,如果出現異常

conn.rollback();默認回滾到conn.setAutoCommit(false);這就相當於代碼只執行到conn.setAutoCommit(false);然後finally運行conn.commit(),提交事務是可以提交的,這就相當於剛開啟事務,然後就提交了事務,中間沒有代碼,數據庫也沒有數據改變。

回滾並不表示結束事務只有提交事務才可以認為是結束事務

dao

package com.itheima.transfer.dao;import java.sql.Connection;import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import com.itheima.utils.DataSourceUtils;import com.itheima.utils.MyDataSourceUtils;public class TransferDao {public void out(String out, double money) throws SQLException {QueryRunner runner = new QueryRunner();Connection conn = MyDataSourceUtils.getCurrentConnection();String sql = "update account set money=money-? where name=?";runner.update(conn, sql, money,out);}public void in(String in, double money) throws SQLException {QueryRunner runner = new QueryRunner();Connection conn = MyDataSourceUtils.getCurrentConnection();String sql = "update account set money=money+? where name=?";runner.update(conn, sql, money,in);}}

dao有兩個方法,一個是轉入,一個是轉出,兩個操作封裝到兩個方法中 ,service會調用這兩個方法。

這個demo只是一種思想,但還有一些問題,下篇文章將優化這個demo,使得connection和service分離


分享到:


相關文章: