您的位置:首页 > 编程语言 > Java开发

Java jdbc事物回滚处理,纯手工打造

2015-08-20 17:18 405 查看
全部个人实践得出结论,如有不到位地方,请大家指正,谢谢(数据库自己随便建个就行)

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();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: