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();
}
}
}
}