事务

transaction
什么是事务?
  将一系列对数据库的操作封装到一个执行流程,
  如果所有操作都能成功,则完成,
  否则所有操作均失败
    事务实现流程:
      A:开启事务 start transaction;
      B:执行SQL操作
      C:如果SQL语句都正常执行,最后要执行 commit 将数据写入到数据库
         如果SQL语句出现问题,执行 rollback 进行回滚操作,这时,数据恢复成事务开始之前的状态
事务实现原理:
  A:非事务实现,执行完一条SQL语句,就马上将数据写入到数据库
  B:事务执行时,执行完SQL语句,数据只是保存在内存中,如果事务执行成功,一次性写入到数据库
     否则就不写
事务与非事务的本质区别
  事务是在内存中操作数据,根据最终结果再决定是否写到磁盘,而非事务是直接操作磁盘

导入数据库连接池工具类
  //一定不要指定线程池,因为要统一con,线程池自己调用con不能保证
  QueryRunner qr = new QueryRunner();
  Connection con = null;
  try {
    con = ...;从连接池获得,(从线程局部变量得到(ThreadLocal)保证每个线程得到的Connection是同一个)
    con.setAutoCommit(false);
    String sql1 = "xxxx";
    qr.update(sql1);
    String sql2 = "xxxx";
    qr.update(sql2);
    con.commit();
  } catch(Exception e) {
    if(con != null){
      con.rollback();
    }
  }
总结:
  DOS命令行下,事务的最终处理依赖于人力判断
  java中的回滚或提交是靠程序实现的,如果没有异常就提交,不然就在catch中回滚

事务提交有两种设置方式:
  方式1:start transaction;
  方式2:set autoCommit = 0;
  SQL语句中针对于单个事务,实现相同
    但是若是多个事务,start transaction 对应的要在每次事务开始时都调用
    但是set autocommit只需要调用一次

一个线程中,只能有一个事务,如果开启另一个事务时,第一个事务会自动提交

ThreadLocal:
  在同一个线程中共享数据,底层是一个Map,有泛型,一个线程中共用的是同一个资源,不同的线程是不同con,两个线程的con互不影响
  get() set() 方法
不用ThreadLocal保存线程时,两个线程有可能共用的是同一个con
(因为加了static,如果不加static,dao层要用con就必须通过传递,增加耦合),
如果共用一个con,一个线程提交,另一个线程也会提交(因为共用的同一个con),数据不安全

事务特性:
  原子性:事务不可分,必须提交或回滚
  一致性:数据操作前后一致
  隔离性:不同的事务之间具有隔离的作用
  持久性:对数据的操作是写在磁盘中的,是永久的

  隔离性:出现的问题
    脏读 不可重复读 虚读/幻读
      read uncommitted 脏读:读到没有提交的数据(update语句),并可以使用
      read commit 不可重复读:另一个事务中提交(update语句)后,此事务即使没有重启也能读到该数据
      repeatable read 幻读:一个事务读取数据时,另一个事务插入数据并提交之后,这个事务数据的更改会更改到刚插入的数据
      serializable 不存在安全问题

MySql:repeatable
Oracle:read committed

posted on 2017-04-21 23:19  刚反面  阅读(120)  评论(0编辑  收藏  举报

导航