jdbc 事务及事务隔离

事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性(ACID):原子性、一致性、隔离性和持久性,只有这样才能成为一个事务。

原子性Atomic

    事务中包含的操作被看作一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。

一致性Consistency

    只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。

隔离Isolation

    事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并发事务的修改必须与其他并发事务的修改相互独立。

持久性Durability

    事务完成之后,它对于系统的影响是永久性的。

事务的并发控制 

    如果不对事务进行并发控制,并发事务的无序执行将会破坏数据的完整性。事务并发执行可能导致的异常可以分为以下几种情况。

Lost update(丢失更新)

    A和B事务并发执行,A事务执行更新后,提交;B事务在A事务更新后,B事务结束前也做了对该行数据的更新操作,然后回滚,则两次更新操作都丢失了。

更新都做白搞了,被一个不争气的事务又还原了!


Dirty Reads(脏读)

    A和B事务并发执行,B事务执行更新后,A事务查询B事务没有提交的数据,B事务回滚,则A事务得到的数据不是数据库中的真实数据。也就是脏数据,即和数据库中不一致的数据。

读了数据库中不存在的数据,感觉被人忽悠了。


Non-repeatable Reads(非重复读)

    A和B事务并发执行,A事务查询数据,然后B事务更新该数据,A再次查询该数据时,发现该数据变化了。

在同一事务中两次读取中被其他事务强行修改,有种横刀夺爱,物是人非的意思。


Second lost updates(第二类丢失更新,可以称为覆盖更新):

    是非重复读的一种特殊情况,即A事务更新数据,然后B事务更新该数据,A事务查询发现自己更新的数据变了。

一个事务修改了数据,事后发现不是按照自己意思修改的,原来是被另外一个事务做了手脚,偷天换日!


Phantom Reads(幻像读)

    A和B事务并发执行,A事务查询数据,B事务插入或者删除数据,A事务再次查询发现结果集中有以前没有的数据或者以前有的数据消失了。

这么多问题,可以分类理解:

事务A查询或修改数据,与此同时事务B也修改数据,根据事务B的完成情况(事务成功完成,事务回滚)可以区分不同问题。

数据库的隔离级别 

    一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。为了兼顾并发效率和异常控制,在标准SQL规范中,定义了4个事务隔离级别。

Read Uncommitted(未提交读):

    即使一个更新语句没有提交,别的事务也可以读到这个改变。如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据。

Read Committed(已提交读):

    更新语句提交以后别的事务才能读到这个改变。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

Repeatable Read(可重复读):

    在同一个事务里面先后执行同一个查询语句的时候,确保得到的结果是一样的。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

Serializable(串行化):

    事务执行的时候不允许别的事务并发执行。事务串行化执行,事务只能一个接着一个地执行,而不能并发执行。

隔离级别对并发的控制 

    各隔离级别对各种异常的控制能力如下表所示,其中Y表示会出现该种异常,N表示不会出现该种异常。

  丢失更新 脏读 非重复读 覆盖更新 幻像读 

未提交读 Y Y Y Y Y 

已提交读 N N Y Y Y 

可重复读 N N N N Y 

串行化 N N N N N 

JDBC事务处理 

    JDBC程序员要负责启动和结束事务,从而确保数据的逻辑一致性。程序员必须定义数据修改的顺序,使数据的修改与业务规则保持一致。程序员将这些修改语句放在一个事务中,使数据库引擎能够强制该事务的物理完整性。

Connection接口定义了事务处理相关的方法:

 void setAutoCommit(boolean autoCommit) 

    设置是否自动提交事务,默认为自动提交。setAutoCommit(false)开始一个事务。

 void setTransactionIsolation(int level) 

    设置事务的隔离级别,事务隔离级别影响事务的并发执行能力。

 void commit() 

    提交事务,使修改动作生效。

 void rollback() 

    回滚事务,撤销修改动作。

原文地址:https://www.cnblogs.com/huangfox/p/2212152.html