MYSQL 之 JDBC(十三):处理事务

所谓事务是指:一组逻辑操作单元,使数据从一种状态变换到另一种状态。

事务的ACID属性

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

为了让多个SQL语句作为一个事务执行:

  • 调用Connection对象的setAutoCommit(false);以取消自动提交事务
  • 在所有SQL语句都执行后,调用commit();方法提交事务
  • 在出现异常时,调用rollback()方法回滚事务
  • 若此时Connection没有被关闭,则需要恢复其自动提交状态

关于事务:

  如果多个操作,每个操作使用的是自己的单独的连接,则无法保证事务。

  具体步骤:

    事务操作开始前,开始事务:取消Connection默认的提交行为;

    如果事务的操作都成功,则提交事务;

    回滚事务:若出现异常,则在catch块中回滚事务。

代码:

  • 新增DAO一个方法,这个方法把Connection提出来作为传参

复制代码

    // 外部来处理Connection
    void update(Connection conn, String sql, Object... args) {
        PreparedStatement ps = null;

        try {
            ps = conn.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, ps, null);
        }
    }

复制代码

测试事务

复制代码

package com.litian.jdbc;

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

/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: TransactionTest.java
 * @time: 2020/4/1 14:06
 * @desc: |
 */

public class TransactionTest {
    public static void main(String[] args) {
        DAO dao = new DAO();

        Connection conn = null;

        try {
            conn = JDBCTools.getConnection();

            // 开始事务:取消默认提交
            conn.setAutoCommit(false);
            String sql = "update t_user2 set money = money - 500 where id = 21023";
            dao.update(conn, sql);

            // 插入错误
            int i = 10 / 0;
            System.out.println(i);

            sql = "update t_user2 set money = money + 500 where id = 21024";
            dao.update(conn, sql);

            // 提交事务
            conn.commit();
        } catch (Exception e) {
            e.printStackTrace();

            try {
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }
}

复制代码

事务的隔离级别

脏读:读取了更新还未提交的数据,但进行了回滚,所以读取的内容是临时的且无效的。
不可重复读:某个事务多次读取一个字段,值却不同,这是因为中间别的事务更新的该字段。
幻读:某个事务从一个表中读取了信息,然后另一个事务更新了该表,使得之前事务再读的时候,表的行数改变了。
数据库提供了4种事务隔离级别

  • READ UNCOMMITED:读未提交数据,3种问题都会出现
  • READ COMMITED:读已提交数据,避免脏读
  • REPEATABLE READ:可重复度,避免脏读和不可重复读
  • SERIALIZABLE:串行化,避免3种问题

Oracle支持2种事务隔离级别:READ COMMITED(默认)和SERIALIZABLE

Mysql支持4种事务隔离级别:默认REPEATABLE READ

在JDBC程序中可以通过Connection的setTransactionIsolation来设置事务的隔离级别

原文地址:https://www.cnblogs.com/hzcya1995/p/13308988.html