事务及安全隐患
事务:Transaction其实指的一组操作,里面包含许多个单一的逻辑。只要有一个逻辑没有执行成功,那么都算失败。所有的数据都回归到最初的状态(回滚)。为什么要有事务? 为了确保逻辑的成功。
使用命令行方式演示事务:
- 开启事务:start transaction;
- 提交或者回滚事务:commit;:提交事务, 数据将会写到磁盘上的数据库
Rollback:数据回滚,回到最初的状态。
使用代码方式演示事务,代码里面的事务,主要是针对连接来的。
- 通过conn.setAutoCommit(false )来关闭自动提交的设置。
- 提交事务 conn.commit();
- 回滚事务 conn.rollback();
事务的四大特性:
1、原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
2、一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
3、隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆, 必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。
4、持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
事务总结:
- 在代码里面会使用事务
conn.setAutoCommit(false);
conn.commit();
conn.rollback();
2.事务只是针对连接连接对象,如果再开一个连接对象,那么那是默认的提交。
3.事务是会自动提交的。
事务的安全隐患 ↓
当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,如果不考虑事务的隔离性,会发生以下几种问题:
1、读的问题
(1)脏读:一个事务读到了另一个事务未提交的数据;
(2)不可重复读:一个事务读到了另一个事务已提交的数据,造成了前后两次查询结果的不一致;
(3)幻读:一个事务读到了另一个事务insert的数据,造成了查询结果不一致。
2、写的问题
(1)丢失更新
两个事务查询数据库数据,存入对应的缓存中(均未提及),当a事务修改数据后(b事务的数据不变),a事务提交,数据库数据发生第一次改变,之后b事务在原数据(缓存中数据)上修改,提交b事务,则会覆盖a事务的结果,造成a事务更新数据失败,即丢失更新
读未提交 引发问题: 脏读
读已提交 解决:脏读 同时引发:不可重复读
可重复读 解决:脏读 、不可重复读 未解决: 幻读
可串行化 解决:脏读、不可重复读 、幻读。
注:mySql 默认的隔离级别是可重复读,Oracle 默认的隔离级别是读已提交
可串行化:如果有一个连接的隔离级别设置为了串行化 ,那么谁先打开了事务,谁就有了先执行的权利, 谁后打开事务,谁就只能得着,等前面的那个事务,提交或者回滚后,才能执行。但是这种隔离级别一般比较少用,容易造成性能上的问题,效率比较低。
- 按效率划分,从高到低
读未提交 > 读已提交 > 可重复读 > 可串行化 - 按拦截程度 ,从高到底
可串行化 > 可重复读 > 读已提交 > 读未提交