JDBC事务处理

一、事务简介

事务处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败,事务本身具有原子性(Atomicity)、一致性(Consistency)、隔离性或独立性(Isolation)、持久性(Durability)等四个特征,这四个特征被称为ACID特性 。
原子性:原子性是事务最小的单元。是不可再分割的单元。相当于一个个小的数据库操作,这些操作必须同时成功,如果一个失败了,则一切的操作将全部失败。
一致性:在数据库操作的前后是一致的,保证数据的有效性,如果事务正常操作则系统会维持有效性,如果事务出现错误,则回到最原始的状态,也要维持其有效性,这样保证了事务开始时和结束时系统处于一致的状态。
隔离性:多个事务可以同时进行且彼此之间无妨访问,只有当事务完成最终操作时,才能看到结果。
持久性:事务完成以后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将会保存。

二、MySQL对事物的支持

序号命令描述 
1SET AUTOCOMMIT = 0取消自动提交处理,开启事务处理 
2SET AUTOCOMMIT = 1打开自动提交处理,关闭事务处理
3START TRANSACTION启动事务
4BEGIN启动事务,相当于执行START TRANSACTION
5COMMIT提交事务
6ROLLBACK回滚全部事务
7SAVEPOINT 事务保存点名称设置事务保存点
8ROOLBACK     TO
SAVEPOINT 事务保存点名称
回滚操作到保存点

三、JDBC事务处理

模拟一个银行转账的程序。
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import util.DbUtil;

public class Bank {

	/**
	 * 转出
	 * @param con
	 * @param accountName
	 * @param account
	 * @throws SQLException
	 */
	private static void outCount(Connection con,String countName,int count) throws SQLException{
		String sql="update t_bank set countBalance=countBalance-? where countName=?";
		PreparedStatement psta = con.prepareStatement(sql);
		psta.setInt(1, count);
		psta.setString(2, countName);
		psta.executeUpdate();
	}
	
	/**
	 * 转入
	 * @param con
	 * @param countName
	 * @param count
	 * @throws SQLException
	 */
	private static void inCount(Connection con,String countName,int count) throws SQLException{
		String sql = "update t_bank set countBalance=countBalance+? where countName=?";
		PreparedStatement psta = con.prepareStatement(sql);
		psta.setInt(1, count);
		psta.setString(2, countName);
		psta.executeUpdate();
	}
	
	public static void main(String[] args) {
		DbUtil dbUtil = new DbUtil();
		Connection con=null;
		try {
			con=dbUtil.getcon(); 
			con.setAutoCommit(false); // 取消自动提交
			System.out.println("张三开始向李四转账!");
			int count=500;
			outCount(con, "张三", count);
			inCount(con, "李四", count);
			System.out.println("转账成功!");
		} catch (Exception e) {
			try {
				con.rollback(); // 回滚
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			try {
				con.commit();  // 提交事务
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

四、设置一个保存点

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;

import util.DbUtil;

public class Bank {

	/**
	 * 转出
	 * @param con
	 * @param accountName
	 * @param account
	 * @throws SQLException
	 */
	private static void outCount(Connection con,String countName,int count) throws SQLException{
		String sql="update t_bank set countBalance=countBalance-? where countName=?";
		PreparedStatement psta = con.prepareStatement(sql);
		psta.setInt(1, count);
		psta.setString(2, countName);
		psta.executeUpdate();
	}
	
	/**
	 * 转出
	 * @param con
	 * @param countName
	 * @param count
	 * @throws SQLException
	 */
	private static void inCount(Connection con,String countName,int count) throws SQLException{
		String sql = "update t_bank set countBalance=countBalance+? where countName=?";
		PreparedStatement psta = con.prepareStatement(sql);
		psta.setInt(1, count);
		psta.setString(2, countName);
		psta.executeUpdate();
	}
	
	public static void main(String[] args) {
		DbUtil dbUtil = new DbUtil();
		Savepoint sp=null;
		Connection con=null;
		try {
			con=dbUtil.getcon(); 
			con.setAutoCommit(false); // 取消自动提交
			System.out.println("张三开始向李四转账!");
			int count=500;
			sp = con.setSavepoint();//设置一个保存点
			outCount(con, "张三", count);
			inCount(con, "李四", count);
			System.out.println("转账成功!");
		} catch (Exception e) {
			try {
				con.rollback(sp); // 回滚到保存点
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			try {
				con.commit();  // 提交事务
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}
假设张三跟李四之间的转账出现小虫子,con.rollback(sp);会回滚到创建sp这个保存点的位置。使张三、李四账户上的钱不变并向上抛出异常等待处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值