点击上方蓝字关注我们

点击上方蓝字关注我们



原子性(Atomicity):保证事务中的操作要么全部成功,要么全部失败,不会只成功一部分。 一致性(Consistency):数据修改的有效性,并且遵循一定的业务规则。 隔离性(Isolation):决定了并发事务之间的可见性和相互影响程度。 持久性(Durability):确保已经提交的事务必须永久生效。

postgres=# \echo :AUTOCOMMITonpostgres=# create table accounts(id serial primary key,user_name varchar(50),balance numeric(10,4));CREATE TABLEpostgres=# alter table accounts add constraint bal_check check(balance >= 0);ALTER TABLEpostgres=# insert into accounts(user_name, balance) values ('usera', 6000);INSERT 0 1postgres=# table accounts;id | user_name | balance----+-----------+-----------1 | usera | 6000.0000(1 row)
postgres=# \set AUTOCOMMIT offpostgres=# \echo :AUTOCOMMIToffpostgres=# begin;BEGINpostgres=*# insert into accounts(user_name, balance) values ('userb', 0);INSERT 0 1postgres=*# table accounts;id | user_name | balance----+-----------+-----------1 | usera | 6000.00002 | userb | 0.0000(2 rows)postgres=*# commit;COMMITpostgres=# table accounts;id | user_name | balance----+-----------+-----------1 | usera | 6000.00002 | userb | 0.0000(2 rows)
postgres=# begin;BEGINpostgres=*# insert into accounts(user_name, balance) values ('userc', 2000);INSERT 0 1postgres=*# table accounts;id | user_name | balance----+-----------+-----------1 | usera | 6000.00002 | userb | 0.00003 | userc | 2000.0000(3 rows)postgres=*# rollback;ROLLBACKpostgres=# table accounts;id | user_name | balance----+-----------+-----------1 | usera | 6000.00002 | userb | 0.0000(2 rows)
postgres=# begin;BEGINpostgres=*# insert into accounts(user_name, balance) values ('userc', 2000);INSERT 0 1postgres=*# savepoint sv1;SAVEPOINTpostgres=*# insert into accounts(user_name, balance) values ('userd', 0);INSERT 0 1postgres=*# table accounts;id | user_name | balance----+-----------+-----------1 | usera | 6000.00002 | userb | 0.00004 | userc | 2000.00005 | userd | 0.0000(4 rows)postgres=*# rollback to sv1;ROLLBACKpostgres=*# commit;COMMITpostgres=# table accounts;id | user_name | balance----+-----------+-----------1 | usera | 6000.00002 | userb | 0.00004 | userc | 2000.0000(3 rows)

脏读(dirty read):一个事务能够读取其他事务未提交的修改。 不可重复读(nonrepeatable read):一个事务读取某个记录后,再次读取该记录时数据发生了改变(被其他事务修改并提交)。 幻读(phantom read):一个事务按照某个条件查询一些数据后,再次执行相同查询时结果的数量发生了变化(另一个事务增加或者删除了某些数据并且完成提交)。幻读和非重复读有点类似,都是由于其他事务修改数据导致的结果变化。 更新丢失(lost update):当两个事务同时读取某一记录,然后分别进行修改提交,就会造成先提交的事务的修改丢失。
Read Uncommitted(读未提交):最低的隔离级别,实际上就是不隔离,任何事务都可以看到其他事务未提交的修改;该级别可能产生各种并发异常。不过,PostgreSQL 消除了 Read Uncommitted 级别时的脏读,因为它的实现等同于 Read Committed。 Read Committed(读已提交):一个事务只能看到其他事务已经提交的数据,解决了脏读问题,但是存在不可重复读、幻读和更新丢失问题。这是 PostgreSQL 的默认隔离级别。 Repeated Read(可重复读):一个事务对于同某个数据的读取结果不变,即使其他事务对该数据进行了修改并提交;不过如果其他事务删除了该记录,则无法再查询到数据(幻读)。SQL 标准中的可重复读可能出现幻读,但是 PostgreSQL 在可重复读级别消除了幻读。 Serializable(可串行化):最高的隔离级别,事务串行化执行,没有并发。

--显示数据库隔离级别show transaction_isolation;--事务中修改隔离级别begin;set transaction isolation level {serializable|repeatable read|read committed|read uncommitted};…………commit;

应用程序先调用各台数据库做一些操作,但不提交事务。然后应用程序调用事务协调器(该协调器可能也是由应用自己实现的)中的提交方法。 事务协调器将联络事务中涉及的每台数据库,并通知它们准备提交事务,这是第一阶段的开始,此时 PostgreSQL 中调用 PREPARE TRANSACTION 命令。 各台数据库接收到 PREPARE TRANSACTION 命令后,PostgreSQL 会将已准备好提交的信息写入持久存储区中,如果无法完成此,会直接返回失败给事务协调器。 事务协调器接收所有数据库的响应。 在第二阶段,如果任何一个数据库在第一阶段返回失败,则事务协调器将会发一个回滚命令 “ROLLBACK PREPARED” 给各台数据库。如果所有数据库的响应都是成功的,则向各台数据库发送 COMMIT PREPARED 命令,通知各台数据库事务成功。
--修改 max_prepared_transactions 参数,重启数据库生效show max_prepared_transactions;alter system set max_prepared_transactions = 10;pg_ctl restartshow max_prepared_transactions;--创建测试表create table testtab01(id int primary key);--开启事务,插入数据并进行第一阶段提交postgres=# begin;BEGINpostgres=*# insert into testtab01 values(1);INSERT 0 1postgres=*# PREPARE TRANSACTION 'osdba_global_trans_0001';PREPARE TRANSACTIONpostgres=# table testtab01;id----(0 rows)--重启数据库后进行第二阶段提交[postgres@localhost ~]$ pg_ctl restartwaiting for server to shut down.... doneserver stoppedwaiting for server to start....2023-07-24 17:01:33.206 CST [10882] LOG: 00000: redirecting log output to logging collector process2023-07-24 17:01:33.206 CST [10882] HINT: Future log output will appear in directory "logs".2023-07-24 17:01:33.206 CST [10882] LOCATION: SysLogger_Start, syslogger.c:674doneserver started[postgres@localhost ~]$ psqlpsql (13.6)Type "help" for help.postgres=# table testtab01;id----(0 rows)postgres=# COMMIT PREPARED 'osdba_global_trans_0001';COMMIT PREPAREDpostgres=# table testtab01;id----1(1 row)

文章转载自KunlunBase 昆仑数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





