zoukankan      html  css  js  c++  java
  • MySql中的事务、JDBC事务、事务隔离级别

    一、MySql事务

    之前在Oracle中已经学习过事务了,这个东西就是这个东西,但是在MySql中用法还是有一点不同,正好再次回顾一下。

    先看看MySql中的事务,默认情况下,每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,就需要开启和结束事务。

    开始事务:start transaction

    结束事务:commit或rollback

    在执行SQL语句之前,先执行start transaction,这就开启了一个新的事务,然后就可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中多条SQL语句造成的影响会持久化到数据库中。rollback表示回滚,一切恢复到事务的起点,事务开始之后所到的操作全当没有发生过。

    在orcale中拿银行转账举过例子,现在在MySql中实现以下:

    首先建了一个银行账户表

    现在张三余额800,李四余额1200,下面李四向张三转账200.

    在两句update语句之后数据库貌似是变了,这时候注意其他用户看到的还是没有变化的数据库,因为没有提交,这时候在本用户查看好像是转成功了,但是一个rollback,一切归于开始。

    二、JDBC事务

    JDBC操作事务,全部都是由Connection完成。Connection的三个方法与事务有关

    setAutoCommit(boolean):设置是否自动提交事务,如果不自动提交,那这句就表示事务的开始。

    commit():表示提交事务

    rollback():表示回滚事务

    JDBC操作事务的代码格式

    try{

     con.setAutoCommit(fasle);

    ....

    ....

    con.commit();

    }catch(){

    con.rollback();

    }

    如果对事务的操作抛出异常,那么肯定就执行不来,所以回滚,要是没有出错,那就提交。

    这里一定要注意的JDBC操作事务一定要使用一个Connection对象!!!!再拿银行转账来演示,首先建一个账户类。

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    
    
    
    /**
     * @author WangXinwei
     *使用自建工具类JdbcUntils返回Connection对象
     */
    public class Bank {
        public void account(String name,int blance) throws SQLException{
             Connection conn=JdbcUntils.getConn();
             String sql="update bank set blance=blance+? where name=?";
             PreparedStatement ps=conn.prepareStatement(sql);
             ps.setInt(1, blance);
             ps.setString(2, name);
             ps.executeUpdate();
         }
    }

    使用JDBC操作事务

    import java.sql.Connection;
    import java.sql.SQLException;
    
    /**
     * @author WangXinwei
     * 传入转账方,收账方,转账金额
     * 
     */
    public class Demo3 {
    
        public void demo(String from, String to, int money) {
            Connection conn = JdbcUntils.getConn();
            try {
                conn.setAutoCommit(false);
                Bank bank = new Bank();
                bank.account(from, -money);
                bank.account(to, +money);
                conn.commit();
            } catch (Exception e) {
                // TODO: handle exception
                try {
                    conn.rollback();
                    conn.close();
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            } finally {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }

    因为我使用的是单例模式返回的Connection对象,所以是一个对象,满足之前说的。

    三、事务的隔离级别

    事务的问题一般都是出现的并发操作的时候。

    并发事务问题有五种,其中两种是更新问题,三种是读问题。重点看并发读问题,在这之前,先略微了解一下更新问题

    1. 第一类丢失更新(lost update): 在完全未隔离事务的情况下,两个事务更新同一条数据资源,某一事务异常终止,回滚造成第一个完成的更新也同时丢失。

    2. 第二类丢失更新(second lost updates):是不可重复读的特殊情况,如果两个事务都读取同一行,然后两个都进行写操作,并提交,第一个事务所做的改变就会丢失。

    并发读问题:

    1.脏读:读到未提交更新数据,就是读到另一个事务未提交数据,就是脏数据。

    比如:

     

    2.不可重复读:对同一记录两次读取不一致,因为另一事务对该记录做了修改

    比如:

     

    3.幻读:对同一张表的两次查询不一致,因为另一事务插入了一条数据

    比如:

     

     不可重复读和幻读有什么区别呢?

    不可重复读是读到了另一个事务的更新

    幻读是读到了另个一表的插入(MySql中无法测试幻读)

     四大隔离级别:

    四个等级的隔离级别,在除了隔离级别不同什么都相同的情况下处理结果是不同的,因为四种隔离级别对并发数据的处理能力是不同的。

    1.SERIALIZABLE(串行化)

    因为是串行化,所以不会出现任何问题,效率最差

    2.REPEATABLE READ(可重复读)MySql默认

    防止脏读和不可重复读,不能防止幻读

    3.READ COMMITTED(读已提交数据)

    防止脏读

    4.READ UNCOMMITTED(读未提交数据)

    可能出现任何问题,效率最好

    查看MySql中隔离级别,使用select @@tx_isolation查看

    也可以通过 set isolationlevel [4选1] 来设置隔离级别

    JDBC设置隔离级别:

    依旧通过Connection对象,使用方法setTransactionisolation[ int level]

    参数可选为

  • 相关阅读:
    Jenkins-maven项目的构建、部署
    配置管理规范-互联网配置管理特点
    Jenkins-权限控制
    Jira-角色和用户组
    Jira-权限管理
    bat命令生成目录树(包含或不包含文件夹)
    登录QQ出现R6030-CRT not initialized,安装QQ 9.2.0可解决
    pointofix快捷键
    卸载Windows的弹窗广告可尝试使用“广告清道夫”
    激活Windows10专业工作站版
  • 原文地址:https://www.cnblogs.com/wxw7blog/p/7881719.html
Copyright © 2011-2022 走看看