JDBC高级篇(MYSQL)—— JDBC中初涉数据库事务

微笑注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接:

package d_transaction;

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

import util.JdbcUtil;

/**
 * 数据库事务:
 * 		比如银行转账:首先从一个账户扣除,再往另一个账户增加(update)
 * 假如在扣除之后,添加的时候出现异常(断网,等等) 
 * 
 * 这个时候就需要数据库的事务功能;
 * 数据库的事务功能,具体是指把转账看成一个事务,在转账的过程中,
 * 要么所有操作一起完成,要么所有操作一起失败!
 * 
 * 事务的原理:
 * 		把每一个操作记录下来;在出现异常的时候进行还原!
 * 
 * mysql操作事务的命令:
 * 		1) 开启事务 set autocommit = 1/0; 
 * 		0: 表示关闭自动提交事务,切换到手动提交事务,相当于开启事务。
 * 		1: 表示自动提交事务,每次执行完一次sql语句,都会提交一次事务(但是提交了之后不能回滚:恢复)
 *   
 *  
 *   
 *  commit:(提交事务) 
 *  	一组sql语句操作成功之后,需要提交事务。
 *  	当事务中的所有操作执行成功之后,要提交事务,事务一旦提交,永久的
 *  	保存到数据库中,且不能回滚! commit;
 *  				
 *  rollback:(回滚事务)
 *  	当事务中的任何一个操作出现问题,可以使用回滚命令,回滚到事务开启的点。
 *  rollback;
 * 
 * 这里需要提到的是,之前在学习存储过程的时候
 * 两个比较常用的全局变量:
 * autocommit和character_set_results
 * 其中 select @@autocommit; -- 就可以看到我们当前的事务是否自动,0手动
 * 在命令行中,我们经常解析中文错误,因为我们设置的utf8
 * 先使用 select @@character_set_results;
 * 但是在cmd中是ASCII编码;所以我们要使用set @@character_set_result=gbk;
 * 
 * 
 * 直接rollback; 就可以返回最初始的状态
 * @author mzy
 * 
 */
public class Demo01 {
	/**
	 * 模拟转账的过程:硬代码,固定转账金额
	 */
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement stmt = null;
		
		
		try {
			conn = JdbcUtil.getConnection();
			// 首先设置autocommit为0,手动的提交事务:false为0,1为true
			conn.setAutoCommit(false);
			// 准备转账的语句
			/**
			 * 从mzy转账2000给jacky
			 */
			// 减去 
			String delSql = "update account set balance=balance-2000 where name='mzy'";
			// 加上
			String AddSql = "update account set balance=balance+2000 where name='jacky'";
			
			stmt = conn.prepareStatement(delSql);
			// 执行
			stmt.executeUpdate();
			
			// 模拟转账中出现异常
			/**
			 * 出现异常之后,一方扣钱,但是另一方却是收不到付款。
			 * 
			 * 这里就需要使用到数据库的事务:
			 * 		事务的使用:一组sql,要么都执行,要么都不执行!
			 */
			// int i = 100/0;
			// 上一次的,要先close,不然会内存泄漏
			stmt.close();
			stmt = conn.prepareStatement(AddSql);
			stmt.executeUpdate();
			
			// 转账成功之后进行commit,事务的提交操作
			conn.commit();
			System.out.println("转账成功!");
			
		} catch (SQLException e) {
			// 当业务中出现异常,任何一条sql执行传问题,都需要进行回滚
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
			
		} finally {
			JdbcUtil.close(stmt, conn);
		}
	}
}
/**
 * 事务的四个特征(ACID):
 * 			1. 原子性:不可再分,要么一起成功,要么一起失败!
 * 			2. 一致性:在操作的前后,体量是不变的,守恒!
 * 较难理解	3. 隔离性:多个事务并发,应该要相互隔离!(重点)
 * 			4. 持久性:一旦提交,改变必须是永久的!即使是数据库崩溃也是可恢复的!
 * 
 * 对事务的隔离性的进一步理解:
 * 		如果事务并发可能产生的问题:
 * 			1) 脏读:
 * 				一个事务读到了另一个事务未提交的更新数据。
 * 
 * 			2) 不可重复读:
 * 				一个事务读到另一个事务已提交的更新数据。
 * 
 * 			3) 幻读:
 * 				一个事务读到了另一个事务新插入的数据。
 * 
 */


原文地址:https://www.cnblogs.com/mzywucai/p/11053472.html