【Java】浅谈JDBC事务处理

本文探讨了在JDBC中进行数据库修改时如何使用事务处理来确保数据的一致性和完整性。通过实例展示了在MySQL数据库中更新数据时,如何避免数据丢失问题,并介绍了如何在事务中设置保存点进行回滚操作。

在进行数据库修改时需注意事务处理问题,否则程序意外停止后会导致数据库数据不正确,下面笔者简单说一下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:只要你还在尝试,就不算失败。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值