JDBC系列:(7)使用Connection操作事务
admin
2023-06-10 11:03:35
0
事务ACID特性
序号特性描述
1原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
3隔离性(Isolation)事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
4持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响




Connection操作事务的相关方法
序号方法作用
1void setAutoCommit(boolean autoCommit)设置事务是否自动提交
如果设置为false,表示手动提交事务。
2void commit() ()手动提交事务
3void rollback()回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)
4Savepoint setSavepoint(String name)在当前事务中创建一个保存点


1、使用事务

package com.rk.db.g_transaction;

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

import com.rk.db.utils.JDBCUtil;

/**
 * // 转账,使用事务
 * @author RK
 *
 */
public class Demo01
{
	public static void main(String[] args)
	{
		Connection conn = null;
		try
		{
			conn = JDBCUtil.getConnection();
			// 1、设置事务为手动提交
			conn.setAutoCommit(false);

			boolean flag = true; //表示是否出现SQL异常
			transferMoney(conn, 100, "张三", "李四",flag);
		}
		catch (SQLException e)
		{
			System.out.println("转账失败!");
			try
			{
				// 2、 出现异常,需要回滚事务
				conn.rollback();
				System.out.println("回滚操作成功!!!");
			}
			catch (SQLException ex)
			{
				ex.printStackTrace();
			}
		}
		finally
		{
			// 3、所有的操作执行成功, 提交事务
			try
			{
				conn.commit();
				System.out.println("执行完毕!");
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
			JDBCUtil.closeQuietly(conn);
		}
	}

	/**
	 * 模拟银行转账
	 * @param conn 数据库连接
	 * @param moneyNum 转账的金额
	 * @param userAdd 收到Money的用户
	 * @param userSub 支出Money的用户
	 * @param flag 是否模拟SQL Exception异常,true表示出现,false表示不出现
	 * @throws SQLException
	 */
	private static void transferMoney(Connection conn, 
			long moneyNum, String userAdd, String userSub,
			boolean flag) throws SQLException
	{
		PreparedStatement pstmtAdd = null;
		PreparedStatement pstmtSub = null;

		try
		{
			String sqlAddMoney = "update T_Bank set money=money+? where username=?";
			pstmtAdd = conn.prepareStatement(sqlAddMoney);
			pstmtAdd.setLong(1, moneyNum);
			pstmtAdd.setString(2, userAdd);
			pstmtAdd.executeUpdate();
			
			if(flag)
			{
				throw new SQLException("模拟SQL执行出错");
			}

			String sqlSubMoney = "update T_Bank set money=money-? where username=?";
			pstmtSub = conn.prepareStatement(sqlSubMoney);
			pstmtSub.setLong(1, moneyNum);
			pstmtSub.setString(2, userSub);
			pstmtSub.executeUpdate();
		}
		finally
		{
			JDBCUtil.closeQuietly(pstmtAdd);
			JDBCUtil.closeQuietly(pstmtSub);
		}

	}
}



2、使用事务,回滚到指定的代码段

package com.rk.db.g_transaction;

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

import com.rk.db.utils.JDBCUtil;

/**
 * // 转账,使用事务, 回滚到指定的代码段
 * @author RK
 *
 */
public class Demo02
{
	public static void main(String[] args)
	{
		Connection conn = null;
		Savepoint sp = null;
		try
		{
			conn = JDBCUtil.getConnection();
			// 1、设置事务为手动提交
			conn.setAutoCommit(false);

			transferMoney(conn, 1000, "李四", "张三",false);
			
			// 如果失败,回滚到这个位置
			sp = conn.setSavepoint();
			
			boolean flag = true; //表示是否出现SQL异常
			transferMoney(conn, 500, "张三", "李四",flag);
		}
		catch (SQLException e)
		{
			System.out.println("转账失败!");
			try
			{
				// 2、 出现异常,需要回滚 (回滚到指定的代码段)
				conn.rollback(sp);
				System.out.println("回滚到指定位置操作成功!!!");
			}
			catch (SQLException ex)
			{
				ex.printStackTrace();
			}
		}
		finally
		{
			// 3、所有的操作执行成功, 提交事务
			try
			{
				conn.commit();
				System.out.println("执行完毕!");
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
			JDBCUtil.closeQuietly(conn);
		}
	}

	/**
	 * 模拟银行转账
	 * @param conn 数据库连接
	 * @param moneyNum 转账的金额
	 * @param userAdd 收到Money的用户
	 * @param userSub 支出Money的用户
	 * @param flag 是否模拟SQL Exception异常,true表示出现,false表示不出现
	 * @throws SQLException
	 */
	private static void transferMoney(Connection conn, 
			long moneyNum, String userAdd, String userSub,
			boolean flag) throws SQLException
	{
		PreparedStatement pstmtAdd = null;
		PreparedStatement pstmtSub = null;

		try
		{
			String sqlAddMoney = "update T_Bank set money=money+? where username=?";
			pstmtAdd = conn.prepareStatement(sqlAddMoney);
			pstmtAdd.setLong(1, moneyNum);
			pstmtAdd.setString(2, userAdd);
			pstmtAdd.executeUpdate();
			
			if(flag)
			{
				throw new SQLException("模拟SQL执行出错");
			}

			String sqlSubMoney = "update T_Bank set money=money-? where username=?";
			pstmtSub = conn.prepareStatement(sqlSubMoney);
			pstmtSub.setLong(1, moneyNum);
			pstmtSub.setString(2, userSub);
			pstmtSub.executeUpdate();
		}
		finally
		{
			JDBCUtil.closeQuietly(pstmtAdd);
			JDBCUtil.closeQuietly(pstmtSub);
		}

	}
}





相关内容

热门资讯

李在明向山西煤矿爆炸事故遇难者... 据凤凰卫视报道,韩国总统李在明5月24日就中国山西省煤矿爆炸事故造成多人遇难表示,向遇难者家属和中国...
华为正式发表半导体领域新定律 人民日报客户端 华为正式发表半导体领域新定律 晶体管密度与系统性能通过逻辑折叠技术实现新突破 202...
武契奇向人民英雄纪念碑敬献花圈 5月25日上午,塞尔维亚总统武契奇前往天安门广场,向人民英雄纪念碑敬献花圈。
重庆多个景区受强降雨影响临时闭... 澎湃新闻记者 廖艳 实习生 林霄近日,受持续强降雨的影响,重庆多个景区出现水位上涨、多处塌方等情况,...
视频丨随迁子女教育保障、异地参... 昨天(22日),《国务院关于推行常住地提供基本公共服务的实施意见》对外发布。文件明确提出,促进未落户...
打造生态链 创新再加速 本报讯 (记者 翁云骞 通讯员 虞昌胜 高博雯) 研发整体效率提升30%,其中代码编写效率提升50%...
前DeepMind华人研究员离... 新智元报道 【新智元导读】前谷歌DeepMind研究员离职并发表长文指出AI行业当前最被低估的瓶颈...
以人工智能应用场景推进数实深度... (来源:天津日报) 转自:天津日报 “十五五”规划纲要提出“全面实施‘人工智能+’行动”,并对构建高...
3名青少年强奸犯免于监禁引众怒... 【文/观察者网 陈思佳】“三名青少年强奸犯免于监禁,引发英国全国争议。”据《国际商业时报》5月24日...
河南省“十五五”规划纲要全文发... 【大河财立方消息】5月25日,河南省国民经济和社会发展第十五个五年规划纲要全文发布。其中提到,提振汽...