1. 程式人生 > >Java jdbc事物回滾處理,純手工打造

Java jdbc事物回滾處理,純手工打造

全部個人實踐得出結論,如有不到位地方,請大家指正,謝謝(資料庫自己隨便建個就行)
Connection conn;建立資料庫連線,來自dao層中的conn
PreparedStatement psta;執行SQL,對照用
conn.setAutoCommit(false);設定事物的提交方式不是自動的
conn.commit();開始執行
conn.rollback();在丟擲異常的地方設定回滾
1、 必須保證servlet中呼叫的Connection必須是dao層中的Connection,如果在servlet中新建Connection會導致事物回滾失敗,這樣就相當於建立了兩個不同的資料庫連線的介面,事物的回滾只能執行servlet中conn的回滾,而dao層中建立的conn並不會執行回滾,方法會執行(也就是資料庫會修改sql執行成功的一部分),這樣可以讓dao層中建立的的conn為全域性變數,然後servlet中呼叫,保證了每個使用者的操作為同一個conn介面
2、 Dao層中的增刪改查方法中的異常儘量用throws SQLException,否則需要在servlet中判斷所執行的方法(增刪改查)是否執行成功(可以設定返回值),如果dao層中捕獲異常(try/catch),就表示在servlet層中執行的方法一定是執行成功的,所以會順序執行conn.commit();導致回滾失敗,但是此種情況加上返回值後可以判斷servlet中呼叫的dao層中的方法是否操作資料庫成功,如果全部成功,則執行conn.commit();,否則不執行,但是這種方法實際是沒有執行回滾操作的,只是停止了conn提交事物,所以資料也是修改不成功的(也就是說這不是正宗的jdbc事物回滾),因此,在dao層丟擲異常,在servlet層捕獲,此時就不需要判斷servlet中呼叫dao層中的方法是否操作資料庫成功,servlet中接收到異常後就會直接執行conn.rollback();,進行真正的jdbc事物回滾
程式碼:
1、 物件,userId為主鍵

package bean;
public class UserInfoBean {
    private int userId;
    private String userName;
    private int userSalary;
    public UserInfoBean() {
    }
    public UserInfoBean(int userId, String userName, int userSalary) {
        this.userId = userId;
        this.userName = userName;
        this
.userSalary = userSalary; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public
int getUserSalary() { return userSalary; } public void setUserSalary(int userSalary) { this.userSalary = userSalary; } }

2、 dao層

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import util.DBUtil;

import bean.UserInfoBean;

public class UserInfoDao {
    public static Connection conn=DBUtil.getConnection();
    public static PreparedStatement psta=null;
    public static ResultSet rs=null;

    /*
     * 根據使用者名稱刪除使用者
     */
    public static int UserInfoDelete(String userName) throws SQLException {
        int result=0;
        //try {
            psta=conn.prepareStatement("delete from userInfo where userName='"+userName+"'");
            result=psta.executeUpdate();
        //} catch (SQLException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        //}
        return result;
    }
    /*
     * 新增使用者,傳進來一個物件
     */
    public static int UserInfoAdd(UserInfoBean ub) throws SQLException{
        int result=0;
        //try {
            psta=conn.prepareStatement("insert into userInfo(userId,userName,userSalary) values(?,?,?)");
            psta.setInt(1, ub.getUserId());
            psta.setString(2, ub.getUserName());
            psta.setInt(3, ub.getUserSalary());
            result=psta.executeUpdate();
        //} catch (SQLException e) {
        //  e.printStackTrace();
        //}
        return result;
    }
}

3、 servlet層

package servlet;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import bean.UserInfoBean;

public class testServlet {
    public static void main(String args[]){
        Connection conn=UserInfoDao.conn; //呼叫dao中的conn,必須
        PreparedStatement psta=UserInfoDao.psta;
        try {
            conn.setAutoCommit(false);//設定事物提交方式
//          psta=conn.prepareStatement("delete from userInfo where userId=8");
//          psta=conn.prepareStatement("insert into userInfo(userId,userName,userSalary) values(4,'zhang',100)");
//          psta.executeUpdate();
//下面5行可以和上面三行交換註釋,自己檢視效果
            int i=UserInfoDao.UserInfoDelete("zhang");
            System.out.println(i);
            UserInfoBean ub=new UserInfoBean(8, "liu", 900);
            int m=UserInfoDao.UserInfoAdd(ub);
            System.out.println("asdfasdfasd"+m);
            //if(i!=0&&m!=0){//dao中丟擲異常就不需要判斷了,可以試試dao層捕獲異常
                conn.commit();//執行事物
            //}
        } catch (SQLException e) {
            try {
                System.out.println("12312");
                conn.rollback();//回滾事物
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }
}