数据库事务简介

事务就是一系列的操作,这些操作完成一项任务.只要这些操作里有一个操作没有成功,事务就操作失败,发生回滚事件.即撤消前面的操作,这样可以保证数据的一致性.而且可以把操作暂时放在缓存里,等所有操作都成功有提交数据库,这样保证费时的操作都是有效操作.
如果没有特殊声明,事务就是指数据库事务简单的讲就是对数据库表的添加、删除、修改和查询操作。
从编程的角度来说事务可由程序员来设置,(何时开启,何时提交,何时回滚)如果没有设置则按数据库默认自动划分事务。而事务最终在数据库上执行.所以要求数据库支持事务。

事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。
1 、原子性
    事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
2 、一致性 
    事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。 
3 、隔离性
    一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
4 、持续性
   也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
  
数据库系统是允许多个用户共享数据库资源,尤其是多个用户可以同时存取相同数据。(多用户同时对一个表操作也就是并发)
我们主观上虽不想这么做,可是这种情况是存在的,没有原因。而并发会破坏事务ACID特性 (隔离性,一致性)。

并发会带来下列问题:
 脏读:一个事务读取了未提交的事务
 不可重复读:同一个事务中多次读取同一个数据返回的结果不同
 幻读:一个事务读取到了另一个事务已提交的insert数据。
 
如果应用程序使用完全隔离的事务,那么同时执行多个事务的效果将与串行执行(一个接一个的顺序执行)完全等效。为解决事务之间的并发带来的个问题,必须在事务之间建立隔离关系(使用隔离级别)。

事务的隔离级别:就是对事务并发控制的等级,ANSI/ISO SQL将其分为串行化(SERIALIZABLE)、可重复读(REPEATABLE READ)、读已提交(READ COMMITED)、读未提交(READ UNCOMMITED)四个等级
    1 Serializable:最严格的级别,事务串行执行,资源消耗最大;
    2 REPEATABLE READ:读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
    3 READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
    4 Read Uncommitted:最低的事务隔离级别,保证了读取过程中不会读取到非法数据。

     隔离级别     脏读        不可重复读     幻读
     Serializable     不会             不会     不会
     REPEATABLE READ     不会             不会       会
     READ COMMITTED     不会               会       会
     Read Uncommitted       会               会       会
  
数据库采用锁机制来实现事务的隔离性。

 共享锁:共享锁用于读取数据操作,它允许其他事务同时读取某锁定的资源,但不允许其他事务更新它。
 排他锁:排它锁用于修改数据的场合。它锁定的资源,其他事务不能读取也不能修改。
 更新锁:更新锁在更新操作的初始化阶段用来锁定可能要被修改的资源,从而避免使用共享锁造成的死锁现象

常见的并发控制锁

http://hahalzb.blogbus.com/logs/19150842.html   心晴怡然

引用:


乐观锁

处理并发更新的一种方式是使用乐观锁(optimistic locking)。乐观锁的工作原理是让应用程序检查它即将更新的数据是否已被另一个事务修改(自该数据上次读取以来)。实现乐观锁的一种常见做法是在每个表里添加一个版本字段,每次应用程序更新数据表记录时就增加这个版本字段。每个UPDATE语句中的WHERE子句会根据上次读取的值来判断这个版本号是否改变。通过查看PreparedStatement.executeUpdate()返回的记录数,应用程序可以判断UPDATE语句是否成功。如果这条记录已被另一个事务更新或删除,应用程序可以回滚这个事务,并重新开始。
在直接执行SQL语句的应用程序中,乐观锁机制的实现非常容易。不过,使用诸如JDO和Hibernate的持久层构架时,实现更为容易,因为它们已将乐观锁作为配置选项提供。一旦启用该配置选项,持久层框架会自动生成SQL UPDATE语句,执行版本检查。第12章将分析乐观锁的使用时机及其缺点,并向你展示怎样在iBATIS、JDO和Hibernate中使用乐观锁。
乐观锁的名称源自如下假定情况,即并发更新的几率极小,此外应用程序并不阻止并发更新,而是检测并发更新,并从并发更新中恢复过来。另一种方式是使用悲观锁(pessimistic locking),它假定并发更新将会发生,因此必须预先阻止。

悲观锁

不同于乐观锁的另一种方式是使用悲观锁。当读取某些记录时,事务先锁住这些记录,这样可以防止其他事务访问这些数据记录。具体细节要视数据库而定,不过糟糕的是,并非所有数据库都支持悲观锁。如果数据库支持悲观锁,在直接执行SQL语句的应用程序中,实现悲观锁非常
容易。然而,正如你所预料的,在JDO或Hibernate应用程序中使用悲观锁更为容易。JDO以配置选项的方式提供悲观锁,而Hibernate则提供一个简单实用的API,来锁定对象。同样,在第12章,你将学习何时使用悲观锁,分析其缺点,并看看怎样在iBATIS、JDO和Hibernate中使用悲观锁。

posted on 2009-11-11 17:23 AK47 阅读(980) 评论(0)  编辑  收藏 所属分类: 数据库


只有注册用户登录后才能发表评论。


网站导航:
 
<2009年11月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

导航

统计

常用链接

留言簿

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜