• JDBC(六)—— 数据库事务


    数据库事务
    事务

    一组逻辑操作单元,使数据从一种状态变换到另一种状态

    事务处理

    保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。

    当在一个事务中执行多个操作时,要么所有事务都提交,要么数据库管理系统放弃所有修改,整个事务回宫到最初状态。

    数据一旦提交就不可回滚

    DDL操作执行自动提交

    DML默认情况下一旦执行,自动提交。可通过set autocommit = false的方式取消DML操作的自动提交

    关闭连接时会自动提交

    支持事物的增删改操作
    /**

    • 支持事务的增删改操作
    • @param conn
    • @param sql
    • @param args
      */
      public void update(Connection conn,String sql,Object ...args){
      PreparedStatement ps = null;
      try {
      //2.预编译sql语句,返回preparedStatement实例
      ps = conn.prepareStatement(sql);
      //3.填充占位符
      //sql占位符的个数与可变形参的长度相同,可变形参相当于一个数组
      for (int i = 0; i < args.length ; i++) {
      ps.setObject(i+1,args[i]);
      }
      //4.执行
      ps.execute();
      } catch (Exception e) {
      e.printStackTrace();
      } finally {
      //5.资源关闭
      JdbcUtils.closeResource(null,ps);
      }
      }
      使用

    public void testTransaction() {
    Connection conn = null;
    try {
    String sql1 = "update transaction set money = money - 100 where name = ?";
    String sql2 = "update transaction set money = money + 100 where name = ?";
    CommonUtils commonUtils = new CommonUtils();
    conn = JdbcUtils.getConnection();

    //取消数据的自动提交功能
    conn.setAutoCommit(false);

    commonUtils.update(conn,sql1,"why");

    commonUtils.update(conn,sql2,"wyy");
    System.out.println("转账成功");

        //提交数据
        conn.commit();
        
    } catch (Exception e) {
        e.printStackTrace();
        try {
            //回滚数据
            conn.rollback();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    } finally {
        JdbcUtils.closeResource(conn,null);
    }
    

    }
    事务的ACID属性及四种隔离级别
    ACID属性
    原子性(Atomicity):指事务是不可分割的单位

    一致性(Consistency):事务必须使数据库从一个一致性转移到另一个一致性状态

    隔离性(Isolation):指一个事务的执行不能被其他事务干扰,一个事务内部的操作及使用的数据对并发的其他事务是隔离的

    持久性(Durability):指事务一旦被提交,对数据库的改变即为永久性的

    数据库并发问题
    脏读

    事务T1,T2

    T1读取了已经被T2更新但是没有提交的字段

    T2回滚,T1读取的内容无效

    不可重复读

    事务T1,T2

    T1读取了一个字段,然后T2更新了该字段.

    之后T1再次读取同一字段,值不同

    幻读

    事务T1,T2

    T1读取了这个表中的某些字段,T2插入了数据

    T1再次相同表的同一字段 增加了几行

    四种隔离级别
    READ UNCOMMITED(读未提交数据)

    允许事务读取未被其他事务提交的变更.

    问题:脏读,不可重复读,幻读

    READ COMMITED(读已提交数据)

    只允许事务读取已经被其他事务提交的变更,避免脏读.

    问题:不可重复的,幻读

    REPEATABLE READ(可重复读)

    雀稗史无可多次从一个字段中读取相同的值,在此期间,禁止其他事务对这个字段进行更新.

    问题:幻读

    SERIALIZABLE(串行化)

    确保十五从一个表读取相同的行,在此期间,禁止其他事务对该表进行更新操作,所有并发问题都可避免,但是性能低下.

    注:

    Oracle数据库支持2种事务隔离:READ UNCOMMITED(读未提交数据)和SERIALIZABLE(串行化),默认为READ UNCOMMITED(读未提交数据)

    Mysql 支持4种事务隔离,默认:REPEATABLE READ(可重复读)

    在MySQL用命令行设置隔离级别
    Mysql常用命令
    进入mysql

    命令行输入:mysql -u用户名 -p密码

    修改密码

    mysqladmin -u用户名 -p旧密码 password 新密码

    添加新用户并赋予相应权限

    grant select on 数据库.* to 用户名@登录主机 identified by “密码”

    显示所有数据库

    show databases

    删除数据库

    drop database <数据库名>

    设置隔离级别
    设置当前连接的隔离级别

    set transaction isolation level read committed;
    设置全局隔离级别

    set global transaction isolation level read committed;
    Java代码设置隔离级别
    conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
    public void testSelect() throws Exception {
    Connection conn = JdbcUtils.getConnection();
    //获取当前隔离级别
    System.out.println(conn.getTransactionIsolation());
    //取消自动提交数据
    conn.setAutoCommit(false);
    //设置数据库隔离级别
    conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
    String sql = "select username,password,reg_date regDate from user where username = ?";
    User user = commonUtils.queryForDifference(conn, User.class, sql, "why");
    System.out.println(user);
    }

    @Test
    public void testUpdae() throws Exception {
    Connection conn = JdbcUtils.getConnection();
    //取消自动提交
    conn.setAutoCommit(false);
    String sql = "update user set username = ? where username = ?";
    commonUtils.update(conn,sql,"love","why");
    Thread.sleep(15000);
    System.out.println("修改结束");
    }

  • 相关阅读:
    用SSMS连接Azure Sql Database 与连接本地库的一些操作区别
    python_高级进阶(3)线程
    python_高级进阶(2)进程与并发
    python_高级进阶(1)进程与并发
    python网络(2)_Udp协议
    python网络(2)_Tcp协议
    python网络(1)_认知
    python异常处理
    python面向对象(5)__特殊双下方法
    python面向对象(4)_细分类的组成成员
  • 原文地址:https://www.cnblogs.com/wwyydd/p/14147859.html
Copyright © 2020-2023  润新知