事务

一、事务

Transaction,其实指的一组操作,里面包含许多个单一的逻辑,只要有一个逻辑没有执行成功,那么就算失败,即所有数据都回归最初的状态(回滚)。

二、为什么要有事务?

为了确保逻辑的成功。例子:银行的转账,假若A用户给B用户转账,A刚做完转账的操作,然后银行停电了,B的账户没有收到钱但是A的余额已经减少了,所以此时是一次不成功的事务,需要回滚都最初未操作的状态。

三、使用命令行

开启事务:start transaction

提交或者回滚事务:

    commit:提交事务,数据会写到磁盘上的数据库

    rollback:数据回滚,回到最初的状态

四、使用代码方式演示事务(重点掌握这三个用法)

1、通过conn.setAutoCommit(false)来关闭自动提交的设置,如果不设置事务会自动提交。

2、提交事务: conn.commit()

3、回滚事务:conn.rollback()

注意:代码的事务针对的是连接,所以都是  连接.操作  ,如果创建了两个连接,一个设置了事务,一个没设置,则使用没设置的连接不会有事务的特性。

五、事务的四个特性(ACID)

原子性Atomicity:事务中包含的逻辑,不可分割

一致性Consistency:事务执行前后,数据完整性

隔离性Isolation:事务在执行期间不应该受到其他事务的影响

持久性Durability:事务执行成功,那么数据应该持久保存在磁盘上

六、事务的安全隐患

不考虑隔离级别设置,那么会出现以下问题。

读:脏读、不可重复读、幻读

   脏读:一个事务可以读取到另一个事务还未提交的数据。 这就会引发 “脏读” 读取到的是数据库内存中的数据,而并非真正磁盘上的数据。

   不可重复读:一个事务读到了另一个事务已提交的数据, 导致前后两次查询结果不一致。

   幻读: 假设一个事务第一次读取表中有十条记录,此时事务二往表中插入一条数据,事务一再次读的时候发现表中有十一条数据了,产生了幻读。

写:丢失更新

    丢失更新:指一个事务去修改数据库, 另一个事务也修改数据库,最后的那个事务,不管是提交还是回滚都会造成前面一个事务的数据更新丢失。(这里指的是针对修改不同的属性,比如一个对象有name=张三 和 age=18,事务一二同时拿到数据,事务一修改的是name=李四,事务二修改的是age=25,因为事务二)

    解决办法:

    悲观锁:默认认为丢失更新一定会发生。代码:select * from 表   for update, 多个一个 for update(数据库机制,排它锁)。所以当A事务发生时,B事务也想访问A事务访问的数据,无法进行,需要等A事务提交或回滚后B事务的操作才能执行。即如果A回滚B得到的是最初的数据,如果A更新则B得到的是A更新后的数据。

    乐观锁:默认认为丢失更新一定不会发生。程序员手动实现,数据可以设置个版本,类似于flag,当A事务拿到数据时数据的flag=0,所以A拿到的也是0,此时B也对此数据操作,也拿到了flag=0,当A操作完毕提交后自己的版本是0,数据库中也是0,匹配成功修改,然后flag改变成1。此时B也操作完毕提交,此时此数据数据库的版本为1,B的版本时0,不匹配,所以操作失败。

七、隔离级别

隔离级别:读未提交、读已提交、可重复读、可串行化

读未提交:一个事务可以读取到另一个事务还未提交的数据。 这就会引发 “脏读” 读取到的是数据库内存中的数据,而并非真正磁盘上的数据。

读已提交:与前面的读未提交刚好相反,这个隔离级别解决了脏读 ,但是只能读取到其他事务已经提交的数据,那些没有提交的数据是读不出来的。但是这会造成一个问题是: 前后读取到的结果不一样。 发生了不可重复读,所谓的不可重复读,就是不能执行多次读取,否则出现结果不一 。

可重复读:该隔离级别, 可以让事务在自己的会话中重复读取数据,并且不会出现结果不一样的状况,即使其他事务已经提交了,也依然还是显示以前的数据,解决了脏读和不可重复读,但是幻读未解决。

可串行化:该事务级别是最高级的事务级别了。比前面几种都要强大一点,也就是前面几种的问题【脏读、不可重复读、幻读】都能够解决。如果有一个连接的隔离级别设置为了串行化,那么谁先打开了事务,谁就有了先执行的权力,谁后打开事务,谁就只能等着,等前面的那个事务提交或者回滚后,才能执行。但是这种隔离级别一般比较少用。容易造成性能上的问题,效率比较低。

按效率划分,从高到低:

    读未提交 > 读已提交 > 可重复读 > 可串行化

按拦截程度,从高到底:

    可串行化 > 可重复读 > 读已提交 > 读未提交

八、不同数据库的默认隔离级别

mySql:默认的隔离级别是  可重复读

Oracle:默认的葛李杰是  读已提交

 

你可能感兴趣的:(JavaWeb)