Postgresql 事务与锁

一:事务:

我们都知道,事务是数据库管理系统中的一个逻辑单位,有有限的操作序列组成,最出名的是其 ACID 4个属性。

  • 原子性(Atomicity),事务中包含的操作,要么全部被执行;要么全部不被执行。

  • 一致性(Consistency),数据库中数据应满足完整性约束。

  • 隔离性(Isolation),数据库中一个事务的执行不应该影响到其他事务。

  • 持久性(Durability),已经提交的事务(状态),其对数据库的修改等应该永久性地保存在数据库中。


事务的用法

1)事务开始,有两种写法:

1)BEGIN;
2) BEGIN TRANSACTION;

2) 事务结束,有两种情况:

1)COMMIT; --确认事务
2)ROLLBACK; --回滚事务


对于测试分析人员,事务的理念也可以运用到分析问题上,比如你想分析一个update/insert/delete SQL语句的执行计划,那么就可以利用事务的概念去更好地管理我们的数据库数据。


我们要分析如下SQL的执行计划:

delete from public."Department" where "DepID" = '1';

那么就可以按照如下方式去执行:

begin;
explain analyze delete from public."Department" where "DepID" = '1';

以上得到了delete SQL语句的执行计划,但是你又不想真正的删除数据,可以继续执行如下语句即可:

rollback;

二:锁

Postgresql中锁的概念和大多数关系型数据库一致,是为了满足事务中数据一致性的目的。一般在并发较高的数据库中,如果不加以控制,可能会出现数据读取和存储不一致的情况。


1)死锁,如果两个事务都在等待对方完成事务,那么就很有可能产生死锁,产生死锁时,postgresql会自动检测到它们,并且会让相关事务都回滚,从而结束它们。确保应该程序以相同的顺序锁定对象,可以有效地避免死锁。

2)其次,锁类型的划分,主要可以分为表级锁和行级锁。其中最普通的两把锁就是Share和Exclusive这两把锁了。其中Share是指读锁,即表的内容就不能修改了,可以为多个事务加上此锁,但是任何一个事务没有释放此锁的话,那么表的内容就不能被修改;Exclusive就是表级的写锁了,获取此锁的事务,如果没有释放,那么其他事务是不能读也不能写的。当然了,后面引入了多版本的机制(MVCC),这种状况有改善,多了2个锁,Access Share/Access Exclusive。其中 Access Share对应的数据库操作一般是select 操作语句;Access Exclusive对应的数据库操作一般是alter table/drop table/truncate/reindex/vacuum full等。


如何更好的避免资源争抢等问题,可以考虑如下方面进行合理规避。

1)在处理高并发地处理一些共享资源时,可以考虑将这种压力重心从关系型数据库转移到in-memory的NO-SQL 数据库,比如redis。前端可以考虑多线程,高并发等业务需求的实现,而关键的后端,可以使用redis自带原生的单线程处理模式即可,其执行效率不一定差。

2)在所有的数据库事务中以相同的次序使用资源。

3)尽量使用较低的隔离级别。


大家也可以扫描关注微信公众号,获取更多性能相关内容:

qrcode_for_gh_39009e949117_258-1.jpg


猜你喜欢

转载自blog.51cto.com/13734261/2540530