zoukankan      html  css  js  c++  java
  • 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("修改结束");
    }

  • 相关阅读:
    什么样的代码称得上是好代码?
    九年程序人生 总结分享
    Docker入门 第一课 --.Net Core 使用Docker全程记录
    阿里云 Windows Server 2012 r2 部署asp.net mvc网站 平坑之旅
    Visual studio 2015 Community 安装过程中遇到问题的终极解决
    Activiti6.0 spring5 工作流引擎 java SSM流程审批 项目框架
    java 进销存 库存管理 销售报表 商户管理 springmvc SSM crm 项目
    Leetcode名企之路
    24. 两两交换链表中的节点
    21. 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/wwyydd/p/14147859.html
Copyright © 2011-2022 走看看