• 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);
            }
        }
    }
    View Code

    事务的隔离级别

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

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

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

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

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

    ————————————————
    版权声明:本文为CSDN博主「李英俊小朋友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_21579045/article/details/105386353

  • 相关阅读:
    js判断是否为数字
    MongoDB 复制集机制及原理
    MongoDB 聚合查询
    C#中时间相关知识点小结
    C#中的小数和百分数计算
    WPF使用VisualTreeHelper进行复杂命中测试
    WPF使用VisualTreeHelperj简单进行命中测试
    WPF Data Binding数据驱动
    WPF Binding中的RelativeSource属性
    WPF特效:流光动画效果
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/13199689.html
走看看 - 开发者的网上家园