数据库事务(Transaction)概述

一.什么是事务(Transaction)

Transaction Overview
A database transaction is a larger unit that frames multiple SQL statements. A transaction ensures that the action of the framed statements isatomicwith respect to recovery.

A SQL Modification Statement has limited effect. A given statement can only directly modify the contents of a single table(Referential Integrityeffects may cause indirect modification of other tables.) The upshot is that operations which require modification of several tables must involve multiple modification statements. A classic example is a bank operation that transfers funds from one type of account to another, requiring updates to 2 tables. Transactions provide a way to group these multiple statements in one atomic unit.

In SQL92, there is no BEGIN TRANSACTION statement. A transaction begins with the execution of a SQL-Data statement when there is no current transaction. All subsequent SQL-Data statements until COMMIT or ROLLBACK become part of the transaction. Execution of aCOMMIT StatementorROLLBACK Statementcompletes the current transaction. A subsequent SQL-Data statement starts a new transaction.

In terms of direct effect on the database, it is theSQL Modification Statementsthat are the main consideration since they change data. The total set of changes to the database by the modification statements in a transaction are treated as an atomic unit through the actions of the transaction. The set of changes either:

Is made fully persistent in the database through the action of the COMMIT Statement, or
Has no persistent effect whatever on the database, through:
the action of the ROLLBACK Statement,
abnormal termination of the client requesting the transaction, or
abnormal termination of the transaction by the DBMS. This may be an action by the system (deadlock resolution) or by an administrative agent, or it may be an abnormal termination of the DBMS itself. In the latter case, the DBMS must roll back any active transactions during recovery.
The DBMSmustensure that the effect of a transaction is not partial. All changes in a transaction must be made persistent, or no changes from the transaction must be made persistent.

Microsoft数据库的事务定义
A transaction is an atomic unit of work that either fails or succeeds. There is no such thing as a partial completion of a transaction. Since a transaction can be made up of many steps, each step in the transaction must succeed for the transaction to be successful. If any one part of the transaction fails, then the entire transaction fails. When a transaction fails, the system needs to return to the state that it was in before the transaction was started. This is known as rollback. When a transaction fails, then the changes that had been made are said to be "rolled back." In effect, this is acting similar to the way the Undo command works in most word processors. When you select undo, the change that you just may have made is reversed. The transaction processing system is responsible for carrying out this undo.

ORACLE数据库的事务定义

  ORACLE事务从COMMIT、ROLLBACK、连接到数据库或开始第一条可执行的SQL语句时开始,到一条COMMIT、ROLLBACK语句或退出数据库时结束。如果在一个事务中包含DDL语句,则在DDL语句的前后都会隐含地执行COMMIT语句,从而开始或结束一个事务。
  如果一个事务由于某些故障或者由于用户改变主意而必须在提交前取消它,则数据库被恢复到这些语句和过程执行之前的状态。
  利用ROLLBACK语句可以在COMMIT命令前随时撤消或回退一个事务。可以回退整个事务,也可以会退部分事务,但是不能回退一个已经被提交的事务。回退部分事务的ROLLBACK命令为:ROLLBACK to savepoint 存储点名存储点是用户放入事务中的标记,用来表示一个可被回退的位置。存储点通过在事务中放入一个SAVEPOINT命令而被插入。该命令的语法是:SAVEPOINT 存储点名如果在ROLLBACK语句中没有给出存储点名,则整个事务被回退。

SYBASE数据库的事务定义

  SYBASE通过使用BEGIN TRANsaction和COMMIT TRANsaction命令指示SQL将任意数目的语句作为一个单元来处理。ROLLBACK TRANsaction命令则允许用户恢复到事务的开始,或恢复到事务内部已经被用SAVE TRANsaction命令定义的存储点上。
  BEGIN TRANsaction和COMMIT TRANsaction能够包含任意数目的SQL 语句和存储过程,方法很简单:BEGIN TRANsaction [事务名称] COMMIT TRANsaction 如果一个事务由于某些故障或者由于用户改变主意而必须在提交前取消它,则数据库被恢复到这些语句和过程执行之前的状态。
  利用ROLLBACK TRANsaction命令可以在COMMIT TRANsaction命令前随时回退一个事务。可以回退整个事务,也可以回退部分事务,但是不能回退一个已经被提交的事务。ROLLBACK TRANsaction命令为:ROLLBACK TRANsaction [事务名¦存储点名] 存储点名是用户放入事务中的标记,用来表示一个可以被回退的位置。存储点名通过在事务中放入一个SAVE TRANsaction命令而被插入。该命令的句法是: SAVE TRANsaction 存储点名如果在ROLLBACK TRANsaction中没有给出存储点名或事务名,则事务被回退到批处理中的第一个BEGIN TRANsaction语句处。

二、事务的属性(ACID)

原子性(ATOMICITY):

一个事务要被完全的无二义性的做完或撤消。在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到以前的状态。

事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。

一致性(CONSISTENCY):

一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致-状态转换到另一个一致状态。举个例子,在关系数据库的情况下,一个一致的事务将保护定义在数据上的所有完整性约束。

事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如B树索引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应用程序已强制所有已知的完整性约束。例如,当开发用于转帐的应用程序时,应避免在转帐过程中任意移动小数点。

隔离性(ISOLATION):

在同一个环境中可能有多个事务并发执行,而每个事务都应表现为独立执行。串行的执行一系列事务的效果应该同于并发的执行它们。

这要求两件事:
在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。
两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。

由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。当事务可序列化时将获得最高的隔离级别。在此级别上,从一组可并行执行的事务获得的结果与通过连续运行每个事务所获得的结果相同。由于高度隔离会限制可并行执行的事务数,所以一些应用程序降低隔离级别以换取更大的吞吐量。

持久性(DURABILITY):

一个被完成的事务的效果应该是持久的。 事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。

事务的ACID只是一个抽象的概念,具体是由RDBMS来实现的。数据库管理系统用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所做的更新,如果某个事务在执行过程中发生了错误,就可以根据日志,撤销事务对数据库已经做的更新,使数据库回退到执行事务前的初始状态。所以不论讲到什么数据库,都会有专门的一章来讲日志

至于事务的隔离性,RDBMS则是采用锁机制来实现的。当多个事务同时更新数据库中的临界数据时,只允许持有锁的事务才能更新该数据,其他事务必须等待,直到前一个数据释放了锁,其他事务才可能有机会来进行更新,这和我们在OS中学的进程的并发时所谈到的锁机制原理差不多。

三、事务与一致性
  事务是完整性的单位,一个事务的执行是把数据库从一个一致的状态转换成另一个一致的状态。因此,如果事务孤立执行时是正确的,但如果多个事务并发交错地执行,就可能相互干扰,造成数据库状态的不一致。在多用户环境中,数据库必须避免同时进行的查询和更新发生冲突。这一点是很重要的,如果正在被处理的数据能够在该处理正在运行时被另一用户的修改所改变,那么该处理结果是不明确的。不加控制的并发存取会产生以下几种错误:
  1、丢失修改(lost updates)
  当多个事务并发修改一个数据时,不加控制会得出错误的结果,一个修改会覆盖掉另一个修改。
  2、读的不可重复性
  当多个事务按某种时间顺序存取若干数据时,如果对并发存取不加控制,也会产生错误。
  3、脏读(DIRDY DATA),读的不一致性
  4、光标带来的当前值的混乱
  事务在执行过程中它在某个表上的当前查找位置是由光标表示的。光标指向当前正处理的记录。当处理完该条记录后,则指向下一条记录。在多个事务并发执行时,某一事务的修改可能产生负作用,使与这些光标有关的事务出错。
  5、未释放修改造成连锁退出
  一个事务在进行修改操作的过程中可能会发生故障,这时需要将已做的修改回退(Rollback)。如果在已进行过或已发现错误尚未复原之前允许其它事务读已做过修改(脏读),则会导致连锁退出。
  6、一事务在对一表更新时,另外的事务却修改或删除此表的定义。
  数据库会为每个事务自动地设置适当级别的锁定。对于前面讲述的问题:脏读、未释放修改造成的连锁退出、一事务在对一表更新时另外的事务却修改或删除此表的定义,数据库都会自动解决。而另外的三个问题则需要在编程过程中人为地定义事务或加锁来解决。

 

四、事务处理类型

自动处理事务:系统默认每个SQL命令都是事务处理 由系统自动开始并提交
隐式事务:当有大量的DDL 和DML命令执行时会自动开始,并一直保持到用户明确提交为止,切换隐式事务可以用SET IMPLICIT_TRANSACTIONS 为连接设置隐性事务模式.当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为 OFF 时,则使连接返回到自动提交事务模式
用户定义事务:由用户来控制事务的开始和结束 命令有: begin tran commit tran rollback tran 命令
分布式事务:跨越多个服务器的事务称为分布式事务,sql server可以由DTc Microsoft distributed  coordinator 来支持处理分布式事务,可以使用 BEgin distributed transaction 命令启动一个分布式事务处理

五、使用事务级别要慎重(与具体DBMS相关)

因为事务级别越高,数量越多、限制性更强的锁就会被运用到数据库记录或者表中。同时,更多的锁被运用到数据库和它们的覆盖面越宽,任意两个事务冲突的可能性就越大。

如果有一个冲突(例如两个事务试图获取同一个锁),第一个事务必将会成功,然而第二个事务将被阻止直到第一个事务释放该锁(或者是尝试获取该锁的行为超时导致操作失败)。

更多的冲突发生时,事务的执行速度将会变慢,因为它们将花费更多的时间用于解决冲突(等待锁被释放)。

阅读更多
换一批

没有更多推荐了,返回首页