读“脏”数据是指事务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:我的钱呢,还我钱!!!!!!!!!