好记性不如烂笔头24-JAVA处理数据库事务(2) - 脏数据


数据是指事务T1修改某一数据,并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被除撤消,而此时T1把已修改过的数据又恢复原值,T2读到的数据与数据库的数据不一致,则T2读到的数据就为数据,即不正确的数据。

脏数据在比较复杂的交互式系统中,非常常见。

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程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。若想关闭这种默认提交方式,让多条SQL在一个事务中执行,可使用下列的JDBC控制事务语句

Connection.setAutoCommit(false);//开启事务(start transaction)

Connection.rollback();//回滚事务(rollback)

Connection.commit();//提交事务(commit)

 

3、JDBC使用事务范例之脏数据 以及读取脏数据的源代码

在JDBC代码中演示银行转帐案例,有两个银行账户,A和B,各自有1000块钱; A往C账户转账100块,然后去读取A账户的钱,读到了A账户只有900块,但是C账户是不存在的,那么这笔钱应该是转账失败。

JAVA源代码:

package com.transaction;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

 

import com.db.EasyC3p0;

 

/**

 *有两个银行账户,A和B,各自有1000块钱;

 *A往C账户转账100块,然后去读取A账户的钱,读到了A账户只有900块,

 *但是C账户是不存在的,那么这笔钱应该是转账失败。

 *

 *@author 范芳铭

 */

public class EasyDirtyData {

    publicstatic void main(String[] args){

        Connectionconn = null;

        PreparedStatementstmt = null;

        ResultSetrs = null;

   

   try{

       conn =EasyC3p0.getConnection();

       //通知数据库开启事务(start transaction)

       conn.setAutoCommit(false);

       String sqlAllMoney = " select sum(money) as money from ffm_account";

       String sqlA_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往C账户转账:

       String sqlA = "update ffm_account set money=money-100 wherename=‘A‘";

       stmt = conn.prepareStatement(sqlA);

       stmt.executeUpdate();

       //系统中没有C账户

       String sqlc = "update ffm_account set money=money+100 wherename=‘C‘";

       stmt = conn.prepareStatement(sqlc);

       stmt.executeUpdate();

       conn.commit();

       //简单模拟A往C账户 结束

       

       //转账结束后,看账户情况

       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

转账执行后,系统中全部金额为:1900

转账执行后,A的金额为:900

 

系统中的钱那里去了,A:我的钱呢,还我钱!!!!!!!!!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。