事务是访问数据库的一个操做序列,数据库应用系统经过事务集来完成对数据库的存取。事务的正确执行使得数据库从一种状态转换成另外一种状态。
 
  事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)的缩写事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)的缩写。
  •   原子性。即不可分割性,事务要么所有被执行,要么就所有不被执行。若是事务的全部子事务所有提交成功,则全部的数据库操做被提交,数据库状态发生转换;若是有子事务失败,则其余子事务的数据库操做被回滚,即数据库回到事务执行前的状态,不会发生状态转换。
  •   一致性或可串性。事务的执行使得数据库从一种正确状态转换成另外一种正确状态。
  • 隔离性。在事务正确提交以前,不容许把该事务对数据的任何改变提供给任何其余事务,即在事务正确提交以前,它可能的结果不该显示给任何其余事务。
  • 持久性。事务正确提交后,其结果将永久保存在数据库中,即便在事务提交后有了其余故障,事务的处理结果也会获得保存。   

  运行嵌入式SQL应用程序或脚本,在可执行SQL语句第一次执行时(在创建与数据库的链接以后或在现有事务终止以后),事务就会自动启动。在启动事务以后,必须由启动事务的用户或应用程序显式地终止它,除非使用了称为自动提交(automatic commit)的过程(在这种状况下,发出的每一个单独的SQL语句被看作单个事务,它一执行就被隐式地提交了)。数据库

  在大多数状况下,经过执行COMMIT或ROLLBACK语句来终止事务。当执行COMMIT语句时,自从事务启动以来对数据库所作的一切更改就成为永久性的了-- 即它们被写到磁盘。当执行ROLLBACK语句时,自从事务启动以来对数据库所作的一切更改都被撤销,而且数据库返回到事务开始以前所处的状态。不论是哪一种状况,数据库在事务完成时都保证能回到一致状态。session

  必定要注意一点:虽然事务经过确保对数据的更改仅在事务被成功提交以后才成为永久性的,从而提供了通常的数据库一致性,但仍是需要用户或应用程序来确保每一个事务中执行的SQL操做序列始终会致使一致的数据库。并发

 

2、数据库系统支持两种事务模式:post

  • 自动提交模式:每一个SQL语句都是一个独立的事务,当数据库系统执行完一个SQL语句后,会自动提交事务。
  • 手动提交模式:必须由数据库客户程序显示指定事务开始边界和结束边界。

  注:MySQL中数据库表分为3种类型:INNODB、BDB和MyISAM,其中MyISAM不支持数据库事务。MySQL中create table 语句默认为MyISAM类型。性能

  

3、对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,若是没有采起必要的隔离机制,就会致使各类并发问题,这些并发问题可概括为如下几类:atom

  • 第一类丢失更新:撤销一个事务时,把其余事务已提交的更新数据覆盖。 
  • 脏读:一个事务读到另外一个事务为提交的更新数据。
  • 虚读:一个事务读到另外一个事务已提交的新插入的数据。
  • 不可重复读:一个事务读到另外一个事务已提交的更新数据。
  • 第二类丢失更新:这是不可重复读中的特例,一个事务覆盖另外一个事务已提交的更新数据。  

 

4、隔离级别版本控制

 

 

 

  当数据库系统采用read Commited隔离级别时,会致使不可重复读喝第二类丢失更新的并发问题,能够在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度,锁能够分为如下几类:blog

  • Serializable(串行化):一个事务在执行过程当中彻底看不到其余事务对数据库所作的更新。
  • Repeatable Read(可重复读):一个事务在执行过程当中能够看到其余事务已经提交的新插入的记录,可是不能看到其余事务对已有记录的更新。
  • Read Commited(读已提交数据):一个事务在执行过程当中能够看到其余事务已经提交的新插入的记录,并且能看到其余事务已经提交的对已有记录的更新
  • Read Uncomitted(读未提交数据):一个事务在执行过程当中能够拷打其余事务没有提交的新插入的记录,并且能看到其余事务没有提交的对已有记录的更新。

    隔离级别越高,越能保证数据的完整性和一致性,可是对并发性能的影响也越大。对于多数应用程序,能够有优先考虑把数据库系统的隔离级别设为Read Commited,它可以避免脏读,并且具备较好的并发性能。尽管它会致使不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,能够由应用程序采用悲观锁或乐观锁来控制。事务

  当数据库系统采用read Commited隔离级别时,会致使不可重复读喝第二类丢失更新的并发问题,能够在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度,锁能够分为如下几类:ci

  A.悲观锁:指在应用程序中显示的为数据资源加锁。尽管能防止丢失更新和不可重复读这类并发问题,可是它会影响并发性能,所以应该谨慎地使用。 

  B.乐观锁:乐观锁假定当前事务操做数据资源时,不回有其余事务同时访问该数据资源,所以彻底依靠数据库的隔离级别来自动管理锁的工做。应用程序采用版本控制手段来避免可能出现的并发问题。

5、悲观锁有两种实现方式。

  A.在应用程序中显示指定采用数据库系统的独占所来锁定数据资源。SQL语句:select ... for update,在Hibernate中使用get,load时如session.get(Account.class,new Long(1),LockMode,UPGRADE) 

  B.在数据库表中增长一个代表记录状态的LOCK字段,当它取值为“Y”时,表示该记录已经被某个事务锁定,若是为“N”,代表该记录处于空闲状态,事务能够访问它。增长锁标记字段就能够实现。

  利用Hibernate的版本控制来实现乐观锁

  乐观锁是由程序提供的一种机制,这种机制既能保证多个事务并发访问数据,又能防止第二类丢失更新问题。

  在应用程序中能够利用Hibernate提供的版本控制功能来视线乐观锁,OR映射文件中的<version>元素和<timestamp>都具备版本控制的功能,通常推荐采用<version>