事务

Posted by CnFeat on June 16, 2016

事务是一件完整的事情,可以包含多个操作单元,这些操作单元要么全部成功,要么全部失败。

MySQL中的事务

MySQL的默认事务是自动提交的。 开启自动事务:

  1. 关闭自动事务

sql set autocommit = off; --针对当前会话有效

  1. 开启一个手动事务

sql start transaction;--开启事务 ... ... commit;--提交 rollback;--回滚

注意:

oracle是手动事务 事务必须提交或者回滚

创建数据库: create database day19; use day19; create table account( name varchar(20), money int ); insert into account values (‘a’,2000); insert into account values (‘b’,2000);

java中的事务控制

connection连接的api

void setAutocommit() //开启事务
void commit()       //提交事务
void rollback()     //回滚
void rollback(Savepoint sp) //还原到指定的还原点
Savepoint setSavepoint()//设置还原点

步骤分析:

  1. 数据库和表
  2. 创建一个项目 导入jar包 驱动,c3p0,dbUtils 工具类、配置文件 datasourceutils c3p0.properties
  3. 编写一个account.jsp 需要有汇款人 收款人 金额 点击转账或者提交的时候提交到servlet(AccountServlet)
  4. AccountServlet操作: 获取三个参数 调用service完成转账 打印信息
  5. service操作 编写一个转账方法 account() 给汇款人减钱,给收款人加钱。 在service层需要控制事务, 若操作全部成功,则提交事务; 若有异常,则事务回滚

需要在service层使用connection对象开始事务,为了保证所有操作在一个事务中,必须保证在service层和dao层所使用的connection是同一个。 方案一:把connection向下传递 方法二:ThreadLocal将使用的连接和当前线程绑定

set(T value) 将value和当前线程绑定 等价于map.put(Thread.currentThread,value); T get() 获取和当前线程绑定的内容 等价于map.get(Thread.currentThread); remove() 解绑和当前线程绑定的内容 等价于map.remove(Thread.currentThread);

在service层绑定,在dao层获取,在service层finally块中释放

使用DBUtils控制事务
  三个核心对象:
    QueryRunner 操作sql语句
    DBUtiles 控制事务,释放资源
    ResultSetHandler 封装结果集

QueryRunner: 构造方法:

    new QueryRunner(); //手动事务,调用方法的时候,需要手动传入一个connection对象,conn需要手动释放资源,手动管理事务
    update(Connection conn,String sql ...);
    query(Connection conn,String sql ...);

事务的总结:

事务的特性: ACID

  • 原子性:事务里面的操作不可分割,要么全部成功,要么全部失败。
  • 一致性:事务提交或回滚之后的状态要和其他的业务状态保持一致。
  • 隔离性:一个事务的操作尽量不要受其他事务的干扰。
  • 持久性:一旦事务提交或者回滚,终要将数据持久化保存到数据库。

不考虑隔离性出现的读问题:

  • 脏读:一个事物读取到另一个事务没有提交的数据
  • 不可重复读:在一个事务中查询两次结果不一致(针对update操作)
  • 幻读(虚读):在一个事务中,两次查询结果不一致。(针对insert操作)

通过设置数据库的隔离级别可以避免一些问题的发生:

  • 隔离级别:

    • read uncommitted : 读未提交 三个问题全存在
    • read committed : 读提交,可避免脏读(Oracle默认隔离级别)
    • repeatable read : 可重复读 避免脏读不可重复读(MySQL默认隔离级别)
    • serializable : 串行化 可避免所有问题