1. 數據表-----BANKACCOUNT
create table BANKACCOUNT
(
id VARCHAR2(255) not null,
name VARCHAR2(255) not null,
balance NUMBER(10)
)
tablespace TS_USER
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
alter table BANKACCOUNT
add primary key (ID)
using index
tablespace TS_USER
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
2. 初始數據
3. Test2.java------------------利用事務模擬簡單的"轉帳"情景
package com.lxh.transaction2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.JOptionPane;
import com.util.ConnectToDB;
public class Test3 {
public Connection conn = null;
public Statement stat = null;
public ResultSet rs = null;
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "轉帳開始:請輸入對方帳號名和轉帳金額");
String name = JOptionPane.showInputDialog("請輸入對方帳戶名:");
String money = JOptionPane.showInputDialog("請輸入轉帳金額:");
if (null == name || "".equals(name) || null == money
|| "".equals(money)) {
JOptionPane.showMessageDialog(null, "帳號和轉帳金額不能爲空");
} else {
// 判斷轉帳金額是否爲數字
char m[] = money.toCharArray();
boolean flag = true;
for (char c : m) {
if (!(Character.isDigit(c))) {
flag = false;
break;
}
}
if (flag) {
int tradeMoney = Integer.parseInt(money);
/**
* 校驗帳戶名和轉帳金額
*/
Test3 t = new Test3();
try {
/**
* 數據庫連接操做
*/
Class.forName("oracle.jdbc.driver.OracleDriver");
t.conn = DriverManager.getConnection(
"jdbc:oracle:thin:@127.0.0.1:1521:tran",
"test", "123");
t.stat = t.conn.createStatement();
/********************** 轉帳前置處理 **********************/
boolean userExist = Test3.checkAccount(t.stat, name);
// 用戶存在
if (userExist) {
// 轉帳帳戶正常
boolean tradeMoneyIsAvail = Test3.checkTradeMoney(
t.stat, "lxh", tradeMoney);// 模擬lxh爲轉出帳戶
if (tradeMoneyIsAvail) {
// 轉帳金額正常
/********************** 轉帳開始 ***************************/
String sql1 = "update bankAccount set balance=balance-"
+ tradeMoney + " where name='lxh'";
String sql2 = "update bankAccount set balance=balance+"
+ tradeMoney + " where name='" + name + "'";
/**
* 設置非自動提交-------很是重要
*/
t.conn.setAutoCommit(false);
// 批處理
t.stat.addBatch(sql1);
t.stat.addBatch(sql2);
/**
* 處理執行SQL的結果
*/
int res[] = t.stat.executeBatch();
int result = 1;// 正常執行,返回結果爲1
for (int i : res) {
result = i;
}
if (1 == result) {
JOptionPane.showMessageDialog(
null,
"轉帳成功,您的當前帳戶餘額爲("
+ Test3.getBalance(t.stat,
"lxh") + ")");
// 執行結果所有爲1的時候執行正確,容許提交
t.conn.commit();
t.conn.setAutoCommit(true);
} else {
// 不符合邏輯(SQL執行出錯),回滾事務
JOptionPane.showMessageDialog(null,
"轉帳失敗。。。請覈查輸入參數");
t.conn.rollback();
}
/********************** 轉帳結束 ***************************/
} else {
JOptionPane.showMessageDialog(
null,
"尊敬的lxh用戶,您的帳戶餘額爲("
+ Test3.getBalance(t.stat, "lxh")
+ ")小於轉帳金額" + tradeMoney
+ ",不能轉帳。");
}
} else {
JOptionPane.showMessageDialog(null, "帳戶: " + name
+ " 不存在,請輸入正確的帳戶名.");
}
/********************** 轉帳前置處理 **********************/
} catch (SQLException e) {
System.out.println("轉帳失敗:\t" + e.getMessage());
try {
// 出現異常回滾(好比數據表名稱/字段名稱有誤,參數有誤)
t.conn.rollback();
t.conn.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} finally {
// 關閉資源
ConnectToDB.closeResultSet(t.rs);
ConnectToDB.closeStatemet(t.stat);
ConnectToDB.closeConnection(t.conn);
}
} else {
// 非數字直接結束
JOptionPane.showMessageDialog(null, "轉帳金額應該爲數字.");
}
}
}
/***************************** 工具方法 *******************************/
// 校驗帳戶名
public static boolean checkAccount(Statement stat, String userName) {
//
boolean flag = true;
//
int result = 0;
//
try {
ResultSet rs = stat
.executeQuery("select count(1) res from bankAccount where name='"
+ userName + "'");
while (rs.next()) {
result = rs.getInt("res");
}
// 賬戶名不存在
if (result != 1) {
flag = false;
}
} catch (SQLException e) {
System.out.println("" + e.getMessage());
}
//
return flag;
}
// 校驗轉帳金額
public static boolean checkTradeMoney(Statement stat, String userName,
int tradeMoneyValue) {
// flag
boolean flag = false;
//
int balance = 0;
// 獲取帳戶金額並判斷轉帳金額是否能夠轉帳
balance = getBalance(stat, userName);
if (tradeMoneyValue <= balance) {
flag = true;
}
//
return flag;
}
// 查詢餘額
public static int getBalance(Statement stat, String userName) {
//
int result = 0;
//
try {
//
ResultSet rs = stat
.executeQuery("select balance from bankAccount where name='"
+ userName + "'");
while (rs.next()) {
result = rs.getInt("balance");
}
} catch (SQLException e) {
System.out.println("獲取帳戶餘額失敗:\t" + e.getMessage());
}
//
return result;
}
}
4. 運行結果
<1> 帳戶名不存在
<2> 金額錯誤
<3> 餘額不足
<4> 轉帳信息(帳戶:xiaowu 金額:500)正確
![](http://static.javashuo.com/static/loading.gif)
5. 結果分析 其實跟"事務的應用demo1-------採用JDBC硬編碼方式實現銀行轉帳."沒有本質區別,只是多了與用戶交互的操做,以及相關數據的驗證和相關信息的顯示。 6. 不足之處:轉帳方是固定的。 固然這只是爲了說明事務的做用作的simple demo,離真正的銀行轉帳邏輯以及實現還有很大差異。 7. 補充: 實際開發中,可能會使用spring來進行事務管理。