JDBC事务之理论篇

事务

事务是数据库操作的基本逻辑单位,一般来说,事务总是并发地执行,并且这些事务可能并发地存取相同的数据。因此为了保证数据的完整性和一致性,所有的JDBC相符的驱动程序都必须支持事务管理。

事务可以理解成 一个操作的序列,Mysql中的事务处理:它是由一个或者多个SQL语句序列结合在一起形成所形成的逻辑处理单元。事物处理中的每一条语句都是完成数据库整个操作任务的一部分,所有的SQL语句结合在一起执行完毕,才能达到完成指定的目的。DBMS在对事务处理中的语句进行处理时,是按照一个约定成俗的规定进行处理的:事务处理中的所有语句都将被作为一个原子性的工作单位,所有语句要么成功的一起执行,要么一个也不执行。

事务本身具有ACID的属性。ACID就是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

原子性( Atomicity):是事务的最小单元,是不可在分割的单元,相当于一个个小的数据库操作,这些操作必须同时成功才为成功,只要有一个失败,则一切的操作都将失败,这就是原子性。

一致性(Consistency):事务在系统完整性中实施一致性,通过保证系统的任何事务最后都处于有效状态来实现。如果事务操作成功,那么系统的所有变化将正确的应用于系统中,系统处于有效状态。如果事务操作中出现错误,那么系统中的所有事务将自动的发生回滚,返回到操作前的状态来保持系统的一致性。

隔离性(Isolation):在隔离的状态执行事务,使它们觉得好像是系统在某一个给定的时间段内执行唯一的操作,如果有两个事务,运行在相同的时间段内,执行着相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用这个系统。

在JDBC中,所有的事务操作都是在Connection对象级别上处理的。Connection是什么?可以说是和数据库的一次对话~    当事务操作完成时,可以通过调用Commit()方法将其最终化。

如果事务中有异常终止,则可以调用rollback()来撤销事务中的操作。

除了commit()和rollBack,MySQL还支持几种事务命令:

1:begin:启动事务相当于执行Start Transaction.     (好像一般不用手动)

2:Start Transaction:启动事务.   (好像一般不用手动)

3:set autocommit=0/1:为0代表取消自动提交处理,开启事务处理;为1代表打开自动提交处理,关闭事务处理,系统默认情况为1.

4:commit:提交事务.

5:rollback:回滚全部事务.

6:savepoint 事务保存点的名称:设置事务保存点.

7:rollback to savepoint 保存点名称:回滚操作到设置的保存点。

讲几个重点,JDBC中,事务管理的默认方式是“自动提交”,也就是当执行完某个新操作之后,系统将自动调用commit()方法。即每个更新操作都呗当作独立的事务执行。所以要自己管理事务或者进行事务管理的时候,一定要先   

  con.setAutoCommit(false);  //默认设的是true

  噢有一点要记一下,就connect在执行close的时候会执行一次commit()

savepoint提供了回滚部分事务的机制。保存点是检查点,当事务操作发生异常时,可以通过设置保存点,将事务回滚到保存点并从该点继续执行。 

可以使用Connection的   setSavePoint()    方法创建保存点,然后运行Connection类的    rollBack(savepointName)  

事务隔离级别

事务隔离级别是用来指定哪些数据对事务中的语句是可视的。

先看当多个事务视图访问相同的的数据时,所可能有的情况:
1.脏读取:

当一个事务修改了某一行数据而未提交,而另一个事务读取了该数据行的值。倘若前一个事务发生了回滚,则后一个事务将得到一个无效的值,这就是所谓的变脏。

(说明提交可以理解是对刚刚所做的这个操作的一个总结,结束的标志,并不是说提交后数据库才有改变,提交前数据库就已经变了。)(后面有隔离级别改善这个)

2.不可重复读取:

当一个事务在读取某一数据行时,另一个事务同时在修改此数据行,则前一事务在重复读取该数据行时将得到一个不一致的值。

3.幻象读取:

当一个事务在进行数据查询时,另一个事务恰好插入了满足查询条件的数据行,则前一个事务在重复读取满足条件的值时,将得到一个额外的值,这就是所谓幻象。

为了解决这些由于多个用户请求相同数据而引起的问题,事务之间必须使用锁相互隔开。多数主流数据库支持不同类型的锁,因此JDBC支持不同类型的事务,它们由Connection对象的setTransactionIsolation()方法指定。在JDBC API中可以获得下列事务级别:

(1)static interesting TRANSACTION_NONE =  0    这是一个特殊的常量,表示JDBC驱动不支持事务。

(2)TRANSACTION_READ_UNCOMMITTED = 1 此级别允许事务查看对数据所做的未提交更改。在此级别,脏读取、不可重复读取和幻象读取都是有可能的。

(3)TRANSACTION_READ_COMMITTED = 2   此级别表示在提交事务之前,在该事务中所做的任何更改在该事务之外都不可视。 这杜绝了脏读取的可能性。

(4)TRANSACTION_REPEATABLE_READ = 3   刺激被表示将读取的行锁定,从而使另一个事务在此事务完成之前不可能更改这些行,这将禁止脏读取和不可重复读取。幻象读取还是有可能的。

(5)TRANSACTION_SERIALIZABLE = 4  在事务期间将表锁定,从而使其他对表添加值或者出去值的事务不能更改WHERE条件,这将杜绝所有类型的数据反常。

运行在TRANSACTION_SERIALIZABLE模式下的事务可以保证最高程度的数据完整性和一致性,但事务保护的级别越高,性能损失就越大。

当创建Connection对象的时候,其事务隔离级别取决于驱动程序,但通常是所涉及的数据库的默认值。用户可以通过setTranctionIsolation()的方法来更改事务的隔离级别。新的级别会在连接过程的剩下时间里面生效。  如果只是想改变一个事务的隔离级别,则必须在该事务开始前进行设置,并在该事务结束后进行复位。不过不建议在事务途中对事务的级别进行更改。

原文地址:https://www.cnblogs.com/wangshen31/p/8849983.html