事务(TRANSACTION)是数据库管理系统执行过程中的一个工作单元,由一个或多个数据库操作序列 构成。
通常,数据库事务会包含了一个序列的对数据库的读/写操作,包含有以下两个目的:
为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态 下仍能保持一致性的方法。 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的 操作互相干扰。
当事务被提交给了数据库管理系统(DBMS),则 DBMS 需要确保该事务中的所有操作都成功完成且其 结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要回滚,回 到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的 运行。
举个例子,当某人在商店通过电子支付购买100元的东西,这个过程至少包括两个操作: 该用户的账户减少 100 元;
商店账户增加100元。 支持事务的数据库管理系统就是要确保以上两个操作(即整个"事务")都能完成,或都取消,否则就会
出现 100 元消失或多出的情况。 因此,事务必须具有以下四个标准属性,通常根据首字母缩写为 ACID:
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执 行,要么都不执行。 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致 状态的含义是数据库中的数据应满足完整性约束。 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
我们可以通过BEGIN TRANSACTION、COMMIT、ROLLBACK命令来控制事务: BEGIN TRANSACTION / BEGIN :开始一个事务。
此类事务通常会持续执行下去,直到遇到下一个 COMMIT 或 ROLLBACK 命令。不过在数据
库关闭或发生错误时,事务处理也会回滚。
COMMIT / END TRANSACTION :事务确认,用于把事务调用的更改保存到数据库中的事务命令。
ROLLBACK:事务回滚,用于撤消尚未保存到数据库的事务命令。
事务控制命令只与 INSERT、UPDATE 和 DELETE 一起使用。他们不能在创建表或删除表时使用,因为 这些操作在数据库中是自动提交的。
例如,我们开始一个事务,从前面课程中举例的部门信息表中删除 d_id = 101 的记录; 然后,我们再通过 ROLLBACK 命令撤消这个的更改。
这样,我们再通过select * from department查询命令可以查询到该表数据还存在。 如果我们开始另一个事务,从部门信息表中删除 d_id = 101 的记录,然后 COMMIT 命令提交所有的更
改,再检查便会发现,表数据已经被删除了。
锁
在多个用户访问数据库的时候若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的 一致性。这个时候便可以通过锁来阻止用户修改一行或整个表,以保持数据库数据的一致性,锁一般用 在并发较高的数据库中。
数据库中有两种基本的锁:排它锁(Exclusive Locks)和共享锁(Share Locks)。 如果数据对象加上排它锁,则其他的事务不能对它读取和修改。 如果加上共享锁,则该数据库对象可以被其他事务读取,但不能修改。
LOCK 命令基础语法如下:
name:要锁定的现有表的名称。如果只在表名之前指定,则只锁定该表。如果未指定,则锁定该 表及其所有子表。 lock_mode:锁定模式指定该锁与哪个锁冲突。如果没有指定锁定模式,则使用限制最大的访问独 占模式。可能的值是:ACCESS SHARE,ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE,ACCESS EXCLUSIVE。
一旦获得了锁,锁将在当前事务中保持,直到事务结束时释放。
当两个事务彼此等待对方完成其操作时,可能会发生死锁。为了防止应用程序遇到这个问题,请确保将 应用程序设计为以相同的顺序锁定对象。
|
BEGIN; DELETE FROM department WHERE d_id = 101; ROLLBACK; |
|
BEGIN; DELETE FROM department WHERE d_id = 101; COMMIT; |
|
LOCK [ TABLE ] name IN lock_mode |
例如我们将数据库中的 department表锁定为 ACCESS EXCLUSIVE 模式。 LOCK 语句只在事务模式下工作,所以我们要先通过BEGIN开始一个事务。
上面的操作将得到LOCK TABLE的结果,表示会保持锁定直到事务结束,要完成这个事务,我们必须提 交或者回滚这个事务。




