JDBC核心技术五 (数据库事务)

系列笔记目录

  1. JDBC核心技术一(概述)
  2. JDBC核心技术二(获取数据库连接)
  3. JDBC核心技术三(PreparedStatement)
  4. JDBC核心技术四(Blob字段和批量插入)
  5. JDBC核心技术五 (数据库事务)
  6. JDBC核心技术六(数据库连接池)
  7. JDBC核心技术七(CallableStatement)

数据库事务是关系型数据库的核心组成,事务的ACID属性保证了数据的安全;

1. 数据库事务介绍

  • 事务:一组逻辑操作单元,使数据从一种状态转换到另一种状态。
  • 事务处理(事务操作): 保证所有事务都作为一个工作单位来执行,即使出现故障,也不能改变这种执行方式(要么所有的事务操作都成功(提交),要么所有的事务操作失败(回滚));

2. JDBC事务处理

  • 数据一旦提交,就不可回滚
  • 数据什么时候意味着提交?
    • 一个连接对象Connection被创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚;
    • 关闭数据库的连接,数据库就会自动提交;
  • JDBC程序中为了让多个SQL语句作为一个事务,可以采用以下方法:
    1. 调用Connection对象的setAutoCommit(false)方法取消自动提交事务;
    2. 在所有SQL语句都成功执行后,调用commit()方法提交事务;
    3. 出现异常时,调用rollback()方法回滚事务;

【案例:用户AA向用户BB转账100】

public void testJDBCTransaction() {
	Connection conn = null;
	try {
		// 1.获取数据库连接
		conn = JDBCUtils.getConnection();
		// 2.开启事务
		conn.setAutoCommit(false);
		// 3.进行数据库操作
		String sql1 = "update user_table set balance = balance - 100 where user = ?";
		update(conn, sql1, "AA");

		// 模拟网络异常
		//System.out.println(10 / 0);

		String sql2 = "update user_table set balance = balance + 100 where user = ?";
		update(conn, sql2, "BB");
		// 4.若没有异常,则提交事务
		conn.commit();
	} catch (Exception e) {
		e.printStackTrace();
		// 5.若有异常,则回滚事务
		try {
			conn.rollback();
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
    } finally {
        try {
			//6.恢复每次DML操作的自动提交功能
			conn.setAutoCommit(true);
		} catch (SQLException e) {
			e.printStackTrace();
		}
        //7.关闭连接
		JDBCUtils.closeResource(conn, null, null); 
    }  
}

其中对数据修改更新update方法为:

public void update(Connection conn ,String sql, Object... args) {
	PreparedStatement ps = null;
	try {
		// 1.获取PreparedStatement的实例 (或:预编译sql语句)
		ps = conn.prepareStatement(sql);
		// 2.填充占位符
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		// 3.执行sql语句
		ps.execute();
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 4.关闭资源
		JDBCUtils.closeResource(null, ps);
	}
}

3. 事务的ACID属性

  1. 原子性(Atomicity)
    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  2. 一致性(Consistency)
    事务必须使数据库从一个一致性状态变换到另外一个一致性状态(如果数据库发生崩溃,提交的事务的执行结果要保持在数据库中)。
  3. 隔离性(Isolation)
    一个事务的执行不能被其它事务干扰,即一个事务内部的操作及使用的数据对并发其它事务是隔离的,并发执行的各个事务之间不能相互干扰;
  4. 持久性
    一个事务一旦被提交,它对数据库中数据的改变就是永久的,接下来的其它操作和数据库故障不应该对其有任何影响;

3.1 数据库的并发问题

  • 访问数据库中相同数据的事务,若没相应的隔离机制,就会导致各种并发问题:
    • 脏读:两个事务T1、T2,T1读取了被T2更新但未提交的数据,之后,若T2回滚T1读取的内容是临时无效的
    • 不可重复读:T1读取了一个字段,之后T2更新了改字段,T1再次读取同一值,值不同了;
    • 幻读:T1读取了一个表的内容,T2向该表中添加了一条记录,T1再次读取同一表,会多出一行;
  • 数据库事务的隔离性:数据库系统必须具备隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题;
  • 隔离级别: 一个事务与其它事务的隔离程度成为隔离级别,隔离级别越高,数据一致性越好,但并发性越弱。

3.2 四种隔离级别

  • 数据库提供的四种事务隔离级别:
    数据库四种事务隔离级别
  • Oracle支持两种事务隔离级别:READ COMMITED、SERIALIZABLE,Oracle默认的事务隔离级别为:READ COMMITED
  • MySQL支持四种事务隔离级别,MySQL的默认事务隔离级别为:REPEATABLE READ。

3.3 JDBC代码中设置隔离级别

    public void testTransactionSelect() throws Exception{
        Connection conn = JDBCUtils.getConnection();
        //获取当前连接的隔离级别
        System.out.println(conn.getTransactionIsolation());
        //设置数据库的隔离级别:
       conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
        //取消自动提交数据
        conn.setAutoCommit(false);

        String sql = "select user,password,balance from user_table where user = ?";
        User user = getInstance(conn, User.class, sql, "CC");
        System.out.println(user);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值