事务(Transaction)是数据库的核心概念,在银行、金融等对数据一致性有强烈要求的系统中应用广泛,为数据库应用以及开发人员必须掌握的基础知识,本文将对事务SQL语句的概念以及使用方法进行一个初步介绍.
![](https://i0.hdslb.com/bfs/article/4adb9255ada5b97061e610b682b8636764fe50ed.png)
事务ACID
事务是访问并可能更新各种数据项的一个程序执行单元(unit),这些步骤集合必须作为一个单一的、不可分割的单元出现.因此,事务要么执行其全部内容,要么就根本不执行.无论事务本身是否失败,或者操作系统崩溃,或者计算机本身停止运行,这项要求都要成立.
数据库事务四大特性: 原子性、一致性、隔离性、持久性. 确保隔离性有可能对系统性能造成较大的不利影响,由于这个原因,一些应用在隔离性上会采取一些妥协.
原子性: 事务的所有操作在数据库中要么全部正确执行,要么全部不不执行.
隔离性: 尽管多个事务可能并发执行,但系统保证,对于任何一对事务T1和T2,在T1看来,T2具体执行到什么程度都不会对自己造成影响. 因此,每个事务都感觉不到系统中有其他事务在并发地执行.
数据库系统必须采取特殊处理(数据库并发控制系统)来确保事务正常执行而不被来自并发执行的数据库语句所干扰.
持久化: 一个事务成功完成后,它对数据库的改变必须是永久的,即使出现系统故障.即使系统能保证一个事务的正确执行,如果此后系统崩溃,执行的结果可能并不能保留下来,那么这项工作的意义也不大了,因此,即使崩溃后事务的操作也必须是持久的,永久的,这种特性称为持久性.
一致性: 一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
换一种表述: 所谓一致性是数据库处理前后结果应与其所抽象的客观世界中真实状况保持一致。这种一致性是一种需要管理员去定义的规则。管理员如何指定规则,数据库就严格按照这种规则去处理数据。(比如:完整性约束规则等)
不一致状态: 由于故障,系统的状态不在反映数据库本应该描述的现实世界的真实状态,我们把这种状态称为不一致状态. 我们必须保证这种不一致性在数据库系统中时不可见的.
但是请注意,系统必然会在事务执行中的某一个时刻处于不一致状态(如事务在执行过程的中间态中).因此,我们需要保证这样的不一致状态除了在事务执行当中以外,在其他时刻是不可见的.
示例一: 假设事务T执行前,账号A和账户B分别有1000元和2000元.事务T(A=A-50;B=B+50)执行后,账号A有950元,账号B有2050元.
事务T执行过程中,仍然存在一个时间账号A包含950元,账号B包含2000元,这显然是不一致状态,然而事务T最终执行完,最终状态会是账号A有950元,账号B有2050元的一致性状态.
示例二: 如果说AB账户总金额5000就是数据库的一致性规则,那么我能不能把A账户转走10000给B,让B账户有10000,而A剩下-5000?从数学上来看完全正确,但这显然是不符合常理的。而这种常理,就是所谓的一致性状态。
![](https://i0.hdslb.com/bfs/article/4adb9255ada5b97061e610b682b8636764fe50ed.png)
事务SQL语句
使用事务处理,确保批量的SQL操作作为一个原子整体,要么完全执行,要么完全不执行,来维护数据库的ACID特性,为此需要配置特定的SQL语法,本节介绍事务SQL语句以及基本使用方法.
隐式事务
默认情况下(没有 BEGIN),PostgreSQL 以 “自动提交” 模式执行事务,即,每条语句都在自己的事务中执行,并且在语句结束时隐式执行提交(如果执行成功,否则执行回滚)。
开启事务语句
BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]
BEGIN 启动一个事务块,即,在 BEGIN 命令之后的全部语句都将在一个事务中执行,直到显式给出了COMMIT或 ROLLBACK。BEGIN 是 PostgreSQL 语言扩展。它等效于 SQL 标准命令START TRANSACTION
START TRANSACTION [ transaction_mode [, ...] ]
功能与 BEGIN 相同;
提交事务语句
COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
AND CHAIN
如果指定了 AND CHAIN,则会立即使用与刚完成的事务相同的的事务特性启动一个新事务。否则,不会启动新事务。可用的事务特性有事务隔离级别、事务访问模式(读/写或只读)和可推迟模式。此外,可以选择一个快照,但只能用于当前事务,不能作为会话默认值。
提交当前事务.事务所做的所有更改对其他人可见,并且在发生崩溃时保证持久性。
END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
END 提交当前事务。事务所做的所有更改对其他人可见,并且在发生崩溃时保证持久性。此命令是 PostgreSQL 扩展,等效于COMMIT。
回滚事务语句
ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
ROLLBACK 回滚当前事务,并导致事务所做的所有更新被丢弃。
ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
ABORT 回滚当前事务,并导致事务所做的所有更新被丢弃。此命令的行为与标准 SQL 命令ROLLBACK 相同,并且仅出于历史原因而存在。
事务处理用来管理insert、update和delete语句.不能回退create或者drop操作,事务处理中可以使用这些语句,但进行回退时,这些操作也不能撤销.(实验验证 postgres可以对create进行回滚)
新建子事务语句
SAVEPOINT savepoint_name
SAVEPOINT 在当前事务中建立一个新的保存点。
保存点是事务中一个特殊的标记,它允许在建立它之后执行的所有命令回滚,将事务状态恢复到保存点时的状态。
简单事务通过rollback和commit就可以实现,复杂的事务可能需要部分提交或者回退.
回滚子事务语句
ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name
回滚在建立保存点后执行的所有命令,然后在相同的事务级别开始一个新的子事务。如果需要,保存点仍然有效,可以再次回滚到该保存点。
ROLLBACK TO SAVEPOINT 隐式销毁在命名保存点之后建立的所有保存点。
释放子事务语句
RELEASE [ SAVEPOINT ] savepoint_name
RELEASE SAVEPOINT 释放命名的保存点和在该命名保存点后创建的所有活动保存点,并释放它们的资源。自创建保存点以来所做的所有更改(尚未回滚的更改)将合并到在创建命名保存点时处于活动状态的事务或保存点中。在 RELEASE SAVEPOINT 之后所做的更改也将成为此活动事务或保存点的一部分。
两阶段事务语句
PREPARE TRANSACTION transaction_id
PREPARE TRANSACTION为两阶段提交准备当前事务。在这个命令之后,该事务不再与当前会话关联。一旦被准备好,事务稍后就可以分别用COMMIT PREPARED或者ROLLBACK PREPARED提交或者回滚。
可以从任何会话而不仅仅是执行原始事务的会话中发出这些命令。如果由于任何原因PREPARE TRANSACTION 命令失败,它会变成一个ROLLBACK:当前事务会被取消。
ROLLBACK PREPARED transaction_id
ROLLBACK PREPARED回滚 一个处于准备好状态的事务。
COMMIT PREPARED transaction_id
COMMIT PREPARED提交一个处于预备状态的事务。
pg默认未开启两阶段提交事务语句,直接使用会产生报错
ERROR: prepared transactions are disabled
开启方法为修改下postgresql.conf中max_prepared_transactions的参数,这个参数默认是0,表示不支持分布式事务;需要改成一个大于0的数字,然后重启数据库(一般设置为与max_connection相同的值)。
普通事务为session级别,prepare transaction将当前事务与当前session分离,进行持久化记录,带来的好处是提高事务提交成功概率。
退出连接之后,当前会话结束,普通的事务也会随着会话结束,但两阶段提交事务不受这个限制,事务依然存在与系统之中。当然在重启postgres系统之后,该事务依然存在。
当重新链接数据库,发现‘tom1’这个事务依然存在,这时我们执行两阶段提交后,发现数据正常显示,完成两阶段事务。
![](https://i0.hdslb.com/bfs/article/4adb9255ada5b97061e610b682b8636764fe50ed.png)
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/25290.html