JDBC事物
Posted junqiang-ma
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC事物相关的知识,希望对你有一定的参考价值。
事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败.
* 事务作用:保证在一个事务中多次操作要么全都成功,要么全都失败.
* 一组操作:同一个连接下的操作 称为一组操作
mysql事务操作
sql语句 描述
start transaction; 开启事务
commit; 提交事务
rollback; 回滚事务
操作:
MYSQL中可以有两种方式进行事务的管理:
自动提交:MySql默认自动提交。及执行一条sql语句提交一次事务。
手动提交:先开启,再提交
JDBC事务操作
* Connection
* setAutoCommit(boolean b) 默认值是true 如果设置成true Mysql自动处理事务 针对的是一条语句
* 如果设置为false 则关闭mysql自动事务 开启手动事务
* commit() 提交事务
* rollBack() 回滚
Connection对象的方法名 描述
conn.setAutoCommit(false) 开启事务
conn.commit() 提交事务
conn.rollback() 回滚事务
DBUtils事务操作
Connection对象的方法名 描述
conn.setAutoCommit(false) 开启事务
new Q 创建核心类,不设置数据源(手动管理连接)
query(conn , sql , handler, params ) 或
update(conn, sql , params) 手动传递连接
DbUtils.commitAndClose(conn) 或
DbUtils.rollbackAndClose(conn) 提交并关闭连接
回滚并关闭连接
* 事务的三个操作
* 1.开启事务:将事务打开 下面的所有操作 都是我当前事务的操作
* 2.提交事务:将事务提交,数据永久保存数据库
* 3.回滚:将数据返回到开启事务之前的状态
*
使用连接池和DBUtils结合 进行转账
* QueryRunner
* 构造方法
* QueryRunner(DataSource d) 连接由QueryRunner自己管理
* query update方法都不需要传入连接
* QueryRunner() 连接对象由我们自己管理
* query update方法都需要传入连接对象
分层概念:
开发中,常使用分层思想
不同的层次结构分配不同的解决过程,各个层次间组成严密的封闭系统
不同层级结构彼此平等
分层的目的是:
解耦
可维护性
可扩展性
可重用性
java.lang.ThreadLocal 该类提供了线程局部 (thread-local) 变量,用于在当前线程中共享数据。
ThreadLocal<T>
* 一条线程存的东西 只能当前线程获取 其他线程获取不到
*
* set(T t)添加元素
* T get() 获取元素
事务特性:ACID
原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)事务前后数据的完整性必须保持一致。
隔离性(Isolation)事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
并发访问问题
如果不考虑隔离性,事务存在3中并发访问问题。
1. 脏读:一个事务读到了另一个事务未提交的数据.
2. 不可重复读:一个事务读到了另一个事务已经提交(update)的数据。引发另一个事务,在事务中的多次查询结果不一致。
3. 虚读 /幻读:一个事务读到了另一个事务已经提交(insert)的数据。导致另一个事务,在事务中多次查询的结果不一致。
解决问题
数据库规范规定了4种隔离级别,分别用于描述两个事务并发的所有情况。
1. read uncommitted 读未提交,一个事务读到另一个事务没有提交的数据。
a) 存在:3个问题(脏读、不可重复读、虚读)。
b) 解决:0个问题
2. read committed 读已提交,一个事务读到另一个事务已经提交的数据。
a) 存在:2个问题(不可重复读、虚读)。
b) 解决:1个问题(脏读)
3. repeatable read :可重复读,在一个事务中读到的数据始终保持一致,无论另一个事务是否提交。
a) 存在:1个问题(虚读)。
b) 解决:2个问题(脏读、不可重复读)
4. serializable 串行化,同时只能执行一个事务,相当于事务中的单线程。
a) 存在:0个问题。
b) 解决:3个问题(脏读、不可重复读、虚读)
安全和性能对比
安全性:serializable > repeatable read > read committed > read uncommitted
性能 : serializable < repeatable read < read committed < read uncommitted
常见数据库的默认隔离级别:
MySql:repeatable read
Oracle:read committed
设置数据库的隔离级别
set session transaction isolation level 级别字符串
级别字符串:read uncommitted、read committed、repeatable read、serializable
例如:set session transaction isolation level read uncommitted;
读未提交:read uncommitted
A窗口设置隔离级别
AB同时开始事务
A 查询
B 更新,但不提交
A 再查询-- 查询到了未提交的数据
B 回滚
A 再查询-- 查询到事务开始前数据
读已提交:read committed
A窗口设置隔离级别
AB同时开启事务
A查询
B更新、但不提交
A再查询--数据不变,解决问题【脏读】
B提交
A再查询--数据改变,存在问题【不可重复读】
可重复读:repeatable read
A窗口设置隔离级别
AB 同时开启事务
A查询
B更新, 但不提交
A再查询--数据不变,解决问题【脏读】
B提交
A再查询--数据不变,解决问题【不可重复读】
A提交或回滚
A再查询--数据改变,另一个事务
串行化:serializable
A窗口设置隔离级别
AB同时开启事务
A查询
B更新--等待(如果A没有进一步操作,B将等待超时)
A回滚
B 窗口--等待结束,可以进行操作
以上是关于JDBC事物的主要内容,如果未能解决你的问题,请参考以下文章