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

好记性不如烂笔头25-JAVA处理数据库事务(3) - 事务回滚点

2015-02-04 16:26 411 查看
在具体的工作中,有的事情需要被保持,不需要回滚,有的工作需要回滚,而这些逻辑,可以通过手动设置事务的回滚点。
1、用JAVA处理数据库事务的事务回滚点的准备
要有一个能够访问数据库的应用。下面的示例都基于ORACLE进行。
create table ffm_account(
   id int primary key ,
   name varchar(32),
   money int
);
测试数据:
insert into ffm_account(id,name,money)values(1,'A',1000);
insert into ffm_account(id,name,money)values(2,'B',1000);
 
2、JDBC中使用回滚点进行事务处理
在JDBC中使用如下的语句设置事务回滚点:
 Savepoint sp = conn.setSavepoint();
 Conn.rollback(sp);
 Conn.commit();//回滚后提交事务
 
3、JDBC使用事务范例之脏数据 以及读取脏数据的源代码
在JDBC代码中演示银行转帐案例,有两个银行账户,A和B,各自有1000块钱;A在银行购买了一个VIP服务,花费10元钱;然后 A往B账户转账100块。
在本样例中,购买VIP服务不需要回滚,A往B账户转账,如果转账失败,需要回滚。
JAVA源代码:
package com.transaction;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
 
import com.db.EasyC3p0;
 
/**
 *有两个银行账户,A和B,各自有1000块钱;A在银行购买了一个VIP服务,花费10元钱;然后 A往B账户转账100块。
 *在本样例中,购买VIP服务不需要回滚,A往B账户转账,如果转账失败,需要回滚。
 *
 *@author 范芳铭
 */
public class EasySavepoint {
    publicstatic void main(String[] args)   throwsSQLException{
        EasySavepointpoint = new EasySavepoint();
        //首先对账户进行操作
        point.OperAccount();
        //查看账户执行情况
        point.afterRunResult();
 
    }
   
    publicvoid OperAccount() throws SQLException{
        Connectionconn = null;
        PreparedStatementstmt = null;
        ResultSetrs = null;
        Savepointsp = null;
        try{
            conn= EasyC3p0.getConnection();
            //通知数据库开启事务(start transaction)
            //=================================
            conn.setAutoCommit(false);
            StringsqlAllMoney = " select sum(money) as money from ffm_account ";
            StringsqlA_money = " select money from ffm_account ";
            stmt= conn.prepareStatement(sqlAllMoney);
            rs = stmt.executeQuery();
            if(rs.next()) {
                System.out.println("转账执行前,系统中全部金额为:" +rs.getInt("money"));
            }
            stmt= conn.prepareStatement(sqlA_money);
            rs= stmt.executeQuery();
            if(rs.next()) {
                System.out.println("转账执行前,A的金额为:"+ rs.getInt("money"));
            }
            //=================================
            //A账户购买VIP服务,花费10元
            StringsqlA = "update ffm_account set money=money-100 where name='A'";
            stmt= conn.prepareStatement(sqlA);
            stmt.executeUpdate();
           
            //设置事务回滚点
            sp= conn.setSavepoint();
           
            //简单模拟A往B账户转账:
            sqlA= "update ffm_account set money=money-100 where name='A'";
            stmt= conn.prepareStatement(sqlA);
            stmt.executeUpdate();
            //系统中有B账户,但是发生了异常
            //简单粗暴的让任务出现异常中断
            intx = 1/0;
            Stringsqlc = "update ffm_account set money=money+100 where name='C'";
            stmt= conn.prepareStatement(sqlc);
            stmt.executeUpdate();
            conn.commit();
            //简单模拟A往B账户 结束
            //=================================
 
 
        }catch (Exception e) {
            //回滚到设置的事务回滚点
            conn.rollback(sp);
            //回滚后要提交事务
            conn.commit();
            e.printStackTrace();
        }finally {
            EasyC3p0.close(conn,stmt, rs);
        }  
    }
   
    publicvoid afterRunResult(){
        Connectionconn = null;
        PreparedStatementstmt = null;
        ResultSetrs = null;
        try{
            conn = EasyC3p0.getConnection();
            //通知数据库开启事务(starttransaction)
            //=================================
            conn.setAutoCommit(false);
            StringsqlAllMoney = " select sum(money) as money from ffm_account ";
            StringsqlA_money = " select money from ffm_account ";
           
            //转账结束后,看账户情况
            stmt= conn.prepareStatement(sqlAllMoney);
            rs= stmt.executeQuery();
            if(rs.next()) {
                System.out.println("转账执行后,系统中全部金额为:" +rs.getInt("money"));
            }
            stmt= conn.prepareStatement(sqlA_money);
            rs= stmt.executeQuery();
            if(rs.next()) {
                System.out.println("转账执行后,A的金额为:"+ rs.getInt("money"));
            }
 
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            EasyC3p0.close(conn,stmt, rs);
        }  
    }
}
 
4、运行结果
转账执行前,系统中全部金额为:2000
转账执行前,A的金额为:1000
java.lang.ArithmeticException: / by zero
    atcom.transaction.EasySavepoint.OperAccount(EasySavepoint.java:64)
    atcom.transaction.EasySavepoint.main(EasySavepoint.java:21)
转账执行后,系统中全部金额为:1900
转账执行后,A的金额为:900
 
系统虽然在运行中出现了异常,但是达到了预期的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息