思维导图–分七个点学习
何为事务?
所谓事务(Transaction)其实就是针对数据库的一组操作, 它由许多单一的逻辑组成,而且再执行的过程中只要有一个逻辑没有执行成功,那么所有的数据都会回到最初的状态。
事务何用?
1、为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
2、当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
3、 可以保证数据的一致性和完整性(避免异常和错误等导致的数据信息异常)
如何使用?
一、命令行方式
- start transaction 开启事务
- commit 提交事务,数据将会写到磁盘上
- rollback 数据回滚,回到最初的状态
- set autocommit = off
演示:
----------------------------------数据库-------------------------------------------
二、java代码
通过conn.setAutoCommit(false)
提交事务conn.commit();
回滚事务conn.rollback();
主要代码部分:
@Test public void testTransaction(){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtil.getConn();
//连接,事务默认就是自动提交的。 关闭自动提交。 conn.setAutoCommit(false);
String sql = "update account set money = money - ? where id = ?";
ps = conn.prepareStatement(sql);
//扣钱, 扣ID为1 的100块钱
ps.setInt(1, 100);
ps.setInt(2, 1);
ps.executeUpdate();
int a = 10 /0 ;
//加钱, 给ID为2 加100块钱
ps.setInt(1, -100);
ps.setInt(2, 2);
ps.executeUpdate();
//成功: 提交事务。
conn.commit();
} catch (SQLException e) {
try {
//事变: 回滚事务
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps, rs);
}
}
事务的特性
原子性—指的是 事务中包含的逻辑,不可分割。
一致性-----指的是 事务执行前后。数据完整性,可以理解为对数据进行操作之后,数据一致变为被操作后的数据
隔离性----指的是 事务在执行期间不应该受到其他事务的影响
持久性----指的是 事务执行成功,那么数据应该持久保存到磁盘上。
事务的安全隐患
读:
1. 脏读
一个事务读到了另一个事务未提交的数据
2. 不可重复读
一个事务读到了另一个事务已提交的数据,造成了前后两次查询结果的不一致;
对于数据库中的某个数据,一个事务范围内多次查询却返回不同的值,这是由于再查询的过程中,数据被另一个事务修改了,这违反了
3. 幻读
一个事务读到了另一个事务insert的数据 ,造成前后查询结果不一致 。
写:
丢失 更新
事务的隔离级别
事务的隔离级别是在数据库操作中,为了有效保证并发读取数据的正确性所采取的一种应对机制,它分为如下四个等级:
- 读未提交
该隔离级别会引发脏读的问题
- 读以提交
该隔离级别能解决脏读的问题,但是会引发不可重读的问题
- 可重复读
该隔离级别能解决脏读、不可重复读的问题,但是会引发幻读的问题
- 可串行化
隔离级别能解决脏读、不可重复读、幻读的问题
按效率划分,从高到低 > 读未提交 > 读已提交 > 可重复读 > 可串行化
按拦截程度 ,从高到底 > 可串行化 > 可重复读 > 读已提交 > 读未提交
丢失更新
丢失更新就是两个事务在查询同一份数据库,并将他们存入对应的缓存中,当事务1对数据进行修改之后,事务1便提交了,此时的数据库发生了改变,之后事务2也对数据库进行了修改,但是此时事务是在第一次查询所获得的数据的基础上进行修改,当事务2提交之后,他会覆盖原有的事务1所提交的数据,这便是丢失更新。
解决方法
- 悲观锁
悲观锁是认定了一定会发生丢失跟新的现象,采用是数据库一种锁机制.(排他锁),在查询的时候加入了 for update
- 原理图:
- 乐观锁
乐观锁认为不一定会发生丢失更新的情况,采用在数据库中添加一个字段完成.
这就是关于事务的学习了!