PostgreSQL中的两阶段提交

    在分布式系统中,事务往往包含了多台数据库上的操作。多台数据库之间的原子性,需要通过两阶段提交协议来实现。

    两阶段提交协议的步骤:

(1)应用程序调用事务协调器中的提交方法。

(2)事务协调器将联络事务中涉及的所有数据库,通知它们准备提交事务(PREPARE TRANSACTION)。

(3)数据库收到通知后,确保后续在被要求提交事务时能提交,或在被要求回滚事务时能回滚,则返回成功,否则返回失败。

(4)事务协调器接收所有数据库的响应。

(5)如果所有数据库都响应成功,则向各个数据库发送提交命令(COMMIT PREPARED)。如果任一数据库返回失败,则向各个数据库发送回滚命令(ROLLBACK PREPARED)。

    下面用实例演示两阶段提交协议。

1.设置参数

     修改postgresql.conf文件中的max_prepared_transactions为10,如果没有设置这个参数,则不能使用两阶段提交。

 set max_prepared_transactions=10;

2.建表

 CREATE TABLE person (
  id  int primary key, 
  name varchar(20)
);

3.准备提交事务

    使用“PREPARE TRANSACTION ”准备提交事务(第一阶段)。

    'person_1'是两阶段提交中全局事务的ID,由事务协调器生成。PostgreSQL数据库成功执行这条命令后,就会把该事务持久化。即使数据库重启,该事务既不会回滚,也不会丢失。

mydb=# begin;
BEGIN
mydb=# insert into person values(1,'April');
INSERT 0 1
mydb=# prepare transaction 'person_1';
PREPARE TRANSACTION 

4.重启数据库

    pg_ctl 用于启动、停止、重启 PostgreSQL 后端服务器。参数 -D 声明该数据库的文件系统位置,如果忽略则使用 PGDATA 环境变量。PGDATA表示缺省数据目录位置。

pg_ctl stop -D $PGDATA
pg_ctl start -D $PGDATA

5.提交事务

    重启后,使用“COMMIT PREPARED”真正提交事务(第二阶段)。

mydb-# commit prepared 'person_1';
COMMIT PREPARED

6.查询数据

select * from person;

  

    由此可见,一旦成功执行“PREPARE TRANSACTION”命令,事务就会被持久化,即使重启数据库,仍然可以提交这个事务。

猜你喜欢

转载自blog.csdn.net/liyazhen2011/article/details/83114638