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

【Java】浅谈JDBC事务处理

2015-02-27 22:24 423 查看
在进行数据库修改时需注意事务处理问题,否则程序意外停止后会导致数据库数据不正确,下面笔者简单说一下JDBC中怎么进行事务处理。

MySQL表结构如下所示:

CREATE table TX_test(id int(11) not null AUTO_INCREMENT,namevarchar(5),money int(11)

,PRIMARY KEY (`id`));

现有数据如下:

id name money

1,"张三",400

2,"李四",10

若使用下面JDBC代码更新数据库:

package txTest;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TxTest {
public static void main(String[] args) throws Exception{
update();
}
public static void update() throws Exception{
try {
Class.forName("com.mysql.jdbc.Driver");  // 注册驱动
} catch (Exception e) {
e.printStackTrace();
}
String dbUrl="jdbc:mysql://localhost:3306/test";
String dbUserName="root";
String dbPassword="root";
Connection conn = null;
Statement st=null;
ResultSet rs=null;
try {
conn = DriverManager.getConnection(dbUrl,dbUserName,dbPassword);
st=conn.createStatement();
String sql01="update tx_test set money=money-10 where name='张三'";
String sql02="update tx_test set money=money+10 where name='李四'";
String sql03="select money from tx_test where name='张三'";
//修改张三账户的钱
st.executeUpdate(sql01);

//查询张三账户的钱,如果钱少于或等于390则抛出运行时异常
float money=0.0f;
rs=st.executeQuery(sql03);
while(rs.next()){
money=rs.getFloat("money");
}
if(money<=390){
throw new RuntimeException("账户所剩余额不多!");
}

//增加李四账户的钱
st.executeUpdate(sql02);
} catch (Exception e) {
e.printStackTrace();
}
//rs.close();
st.close();
conn.close();
}
}


最终数据如下:

id name money

1,"张三",390

2,"李四",10

我们发现张三的钱少了,可是李四的钱并没有增加,这样就凭空消失了10元,违反了事务的原子性。将代码更改一下:

package txTest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TxTest {
public static void main(String[] args) throws Exception{
update();
}
public static void update() throws Exception{
try {
Class.forName("com.mysql.jdbc.Driver");  // 注册驱动
} catch (Exception e) {
e.printStackTrace();
}
String dbUrl="jdbc:mysql://localhost:3306/test";
String dbUserName="root";
String dbPassword="root";
Connection conn = null;
Statement st=null;
ResultSet rs=null;
try {
conn = DriverManager.getConnection(dbUrl,dbUserName,dbPassword);
//关闭Connection自动提交
conn.setAutoCommit(false);
st=conn.createStatement();
String sql01="update tx_test set money=money-10 where name='张三'";
String sql02="update tx_test set money=money+10 where name='李四'";
String sql03="select money from tx_test where name='张三'";
//修改张三账户的钱
st.executeUpdate(sql01);

//查询张三账户的钱,如果钱少于或等于390则抛出运行时异常
float money=0.0f;
rs=st.executeQuery(sql03);
while(rs.next()){
money=rs.getFloat("money");
}
if(money<=390){
throw new RuntimeException("账户所剩余额不多!");
}

//增加李四账户的钱
st.executeUpdate(sql02);
//提交操作
conn.commit();
} catch (Exception e) {
if(conn!=null){
//回滚事务
conn.rollback();
}
e.printStackTrace();
}
//rs.close();
st.close();
conn.close();
}
}


最终输出的数据仍为张三的钱是390,表示再一次运行程序后张三没有没扣钱。
id name money

1,"张三",390

2,"李四",10

如果在回滚中需要设置回滚保存点的话可用Savepoint接口,在需要设置回滚点的代码后面加上sp=conn.setSavepoint();代码,提交时用conn.rollback(sp); conn.commit();进行提交。

Author:事始

Sign:只要你还在尝试,就不算失败。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: