您的位置:首页 > 数据库 > MySQL

Mysql事务分析

2017-06-09 15:14 141 查看
事务:就是一件完整的事情,包含多个操作单元,这些操作单元要么全部成功,要么全部失败

例如:转账(转入,转出同时进行)

A. Mysql中的事务:

a. Mydql中的事务是自动提交的,一条sql就是一个事物

b. 开启手动事务方式

i. 关闭自动事务(了解针对当前窗口)

1) Set autocommit = off;

2) 提交commit;

3) 撤销Rollback

ii. 手动开启一个事务

1) Start transaction; 开启一个事务

2) Commit; 事务提交

3) Rollback; 事务回滚

iii. 扩展:oracel中的事务默认是手动的,必须手动提交

B. Java中的事务:

a. Connection接口中的api

i. SetAutoCommit(false); 手动开启事务

ii. Commit(); 事务提交

iii. Rollback();事务回滚

b. 扩展:回滚点

i. Void rollback(Savepoint savepoint);还原到哪个地方

ii. Savepoint setSavepoint():设置还原点

C. Jdbc控制java中的事务

i. 一旦出现异常,钱已经进行扣除,但是接收方并没有转入

ii. 为了避免这种问题,必须添加事务,在service中添加事务

iii. 为了保证所有的操作在同一个事务中,必须使用的是同一个conn连接,因为Java开启的是一条连接的事务

iv. 在service层中我们获取了连接,开启了事务,如何在dao层中使用开启了事务的连接呢?

i. 方法一:

i. 向下传递参数

ii. 注意:conn不能再dao层释放,在哪里获取的在哪里释放,所以应该在service中释放

ii. 方法二:

i. 方法一代码侵入

ii. 可以将我们的connection绑定到当前线程

iii. jdk中有一个类ThreadLocal类 实例通常是类中的private static字段,他们希望将状态与某一个线程(例如,用户Id事务id)相关联

iii. ThreadLocal的方法

i. 构造:

a) New ThreadLocal();

ii. 设置:

a) Set( T value):将内容和当前线程绑定

iii. 得到:

a) Void Get():获取和当前线程绑定的内容

iv. 解绑:

a) Remove():将当前内容和内容解绑

v. 内部维护了一个map集合

a) Map.put(当前线程,内容)

b) Map.get(当前线程)

c) Map.remove(当前线程)

D. DButils框架控制我们的事务

i. 创建queryrunner

ii. 编写sql

iii. 执行sql

E. queryRunner:

i. 构造:

i. New QueryRunner(DataSource ds):自动事务

ii. New QueryRunner():手动事务

ii. 常用方法:

i. Update(Connction线程中获取的,String sql,Onject….params)执行cud

ii. Query()

F. 事务的总结:

i. 事务的特性:

i. ACID

ii. A 原子性:事务里面的操作单元不可切割,要么全部成功,要么全部失败

iii. C 一致性:事务执行前后,业务状态要和其他的业务状态保持一致

iv. I 隔离性:一个事务执行的时候最好不要收到其他事务的影响

v. D 持久性:一旦事务提交或者回滚,都要持久化到我们的数据库中

ii. 不考虑隔离性会出现的读问题

i. 脏读:在一个事务中,读取到另一个事物没有提交的数据

ii. 不可重复读:在一个事务中,两次查询的结果不一致(针对update操作)

iii. 虚读(幻读):在一个事务中,两次查询的结果不一致(针对insert操作)

iii. 通过设置数据库的隔离级别来避免以上的问题

i. Read uncommited 读未提交 上面的三个问题都会出现

ii. Read commited 读已提交 避免脏读的发生

iii. Repeatabe read 可重复读 避免脏读和不可重复读的发生

iv. Serializable 串行化 避免所有的问题

了解

演示脏读的发生:

将数据库的隔离级别设置成 读未提交

set session transaction isolation level read uncommitted;

查看数据库的隔离级别

select @@tx_isolation;

避免脏读的发生,将隔离级别设置成 读已提交

set session transaction isolation level read committed;

不可避免不可重复读的发生.

避免不可重复读的发生 经隔离级别设置成 可重复读
set session transaction isolation level  repeatable read;

演示串行化 可以避免所有的问题
set session transaction isolation level  serializable;
锁表的操作.

四种隔离级别的效率
read uncommitted>read committed>repeatable read>serializable
四种隔离级别的安全性
read uncommitted<read committed<repeatable read<serializable

开发中绝对不允许脏读发生.
mysql中默认级别:repeatable read
oracle中默认级别:read committed

java中控制隔离级别:(了解)
Connection的api
void setTransactionIsolation(int level)
level是常量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  事务 sql mysql