PG中支持两阶段提交协议

PG中支持两阶段提交协议

在分布式系统中,事物往往包含了多台数据库上的操作。单台数据库的操作能保证原子性,而多台数据库之间的原子性,就需要通过两阶段提交来实现了,两阶段提交是实现分布式事物的关键。

两阶段提交有如下五个步骤:
1、应用程序先调用各台数据库做一些操作,但不提交事物;然后调用事物协调器(这个协调器可能也是由应用自己实现的)中的提交方法。
2、事务协调器将联络事务中涉及的每台数据库,并通知它们准备提交事物,这是第一阶段的开始。在PG一般是调用“PREPARE TRANSACTION”命令。
3、各台数据库接收到“PREPARE TRANSACTION”命令后,如果要返回成功,则数据库必须将自己置于一下状态:确保后续能在被要求提交事物时提交事物,或者在被要求回滚事物时能回滚事物。所以PG会将已准备好提交的信息写入持久存储区中。
如果数据库无法完成此工作,它会直接返回失败给事物协调器。
4、事物协调器接收到所有数据库的响应。
5、在第二阶段,如果任意数据库在第一阶段返回失败,则事物协调器将会发出一个回滚命令(ROLLBACK PREPARED)给各台数据库。如果所有数据库的响应都是成功的,则向各台数据库发送“COMMIT PARAPARED”命令,通知各台数据库事物成功。


以下为实验演示第二阶段提交:
首先必须将max_prepared_transactions设置为大于0的值。
注意:设置该参数需要重启数据库,直接设置这个参数是不能成功的,如下:
[highgo@sourcedb ~]$ psql
psql (3.1.4)
Type "help" for help.
highgo=# select version();
              version               
------------------------------------
 HighGo Database 3.1.4 Linux 64-bit
(1 row)

highgo=# set max_prepared_transactions = 10;
错误:  在没有启动服务器的情况下,不能改变参数 "max_prepared_transactions" 
highgo=# 

下面修改postgresql.conf中的max_prepared_transactions为10,并且重启数据库使之生效

[highgo@sourcedb data]$ pg_ctl stop
waiting for server to shut down.... done
server stopped
[highgo@sourcedb data]$ pg_ctl start
server starting
[highgo@sourcedb data]$ 日志:  日志输出重定向到日志收集进程
提示:  后续的日志输出将出现在目录 "hgdb_log"中.


[highgo@sourcedb data]$ psql
psql (3.1.4)
Type "help" for help.
highgo=# show max_prepared_transactions
;
 max_prepared_transactions 
---------------------------
 10
(1 row)


highgo=# create table test01(id int primary key);
CREATE TABLE
highgo=# begin;
BEGIN
highgo=# insert into test01 values(1);
INSERT 0 1
使用“PREPARE TRANSACTION”命令准备好事物提交(第一阶段)
highgo=# PREPARE TRANSACTION 'pre_trans_01';
PREPARE TRANSACTION


命令中'pre_trans_01'是两阶段提交中 全局事物的ID,由事物协调器生成(事物协调器也可能是由应用实现的,事物协调器会持久化这个全局事物ID。PG数据库一旦成功执行这条命令,就会把此事物持久化,意思是即使重启数据库,此事物就不会回滚也不会丢失)。


到这里,停止数据库然后重启:
highgo=# \q
[highgo@sourcedb data]$ pg_ctl stop
waiting for server to shut down.... done
server stopped
[highgo@sourcedb data]$ pg_ctl start
server starting
[highgo@sourcedb data]$ 日志:  日志输出重定向到日志收集进程
提示:  后续的日志输出将出现在目录 "hgdb_log"中.


重启后使用“COMMIT PREPARED”真正提交这个事物(第二阶段):
[highgo@sourcedb data]$ psql
psql (3.1.4)
Type "help" for help.
highgo=# COMMIT PREPARED 'pre_trans_01';
COMMIT PREPARED
highgo=# SELECT * FROM TEST01;
 id 
----
  1
(1 row)


从上面的例子中可以看出,一旦成功执行“PREPARE TRANSACTION”命令,事物就会被持久化,即使重启数据库,仍然可以提交这个事物,事物中的操作不会丢失。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值