事务是一组数据库操作的集合,这些操作作为一个整体被执行,要么全部成功,要么全部失败,数据库会从一个一致性状态转换到下一个一致性状态。即使在系统故障的情况下,也能保证数据的一致性。
如果事务中的某个操作失败,那么整个事务将被回滚,数据库状态将恢复到事务开始之前的状态。
TDSQL PG事务系统通过使用多版本并发控制(MVCC)和快照隔离等技术,提供了高效的并发控制和严格的事务隔离,确保并发执行的事务不会互相干扰。在MVCC中查询数据获取的锁不会与写入数据获取的锁发生冲突,因此读取不会阻塞写入,写入也不会阻塞读取,可以为用户提供高性能并发读写能力。
事务隔离级别
TDSQL PG支持四种事务隔离级别,这些级别定义了一个事务可能会看到其他并发事务所做更改的程度。这些级别从低到高分别是:
- Read Uncommitted(读未提交):这是最低的隔离级别,一个事务可能会看到其他事务未提交的更改。
- Read Committed(读已提交):这是TDSQL PG默认隔离级别。在这个级别,一个事务能看到在该事务开始之前已经提交事务所做的更改,后续的查询也会看到其他事务所提交新的更改。
- Repeatable Read(可重复读):在这个级别,一个事务在其整个过程中看到的是一个一致的快照。也就是说,它只能看到在该事务开始时已经提交的事务所做的更改,而不能看到在该事务进行期间其他事务所提交的更改。
- Serializable(可串行化):这是最高的隔离级别。它提供了最严格的隔离级别,确保事务序列化执行,即使在并发执行时也能得到相同的结果。这个级别可以防止所有类型的并发问题。
锁
TDSQL PG还提供了表级和行级锁定,为应用提供显式管理互斥场景的能力;TDSQL PG支持咨询锁,提供了跨事务的锁机制;整体上为应用提供了更高的灵活度。
表级锁
TDSQL PG提供了多种锁模式来控制对表中数据的并发访问。在多版本并发控制(MVCC)无法提供所需行为的情况下,这些模式可以用于应用程序显式执行锁定动作。注意,TDSQL PG支持的命令会自动获取合适的锁,确保在命令执行期间操作的表不会被删除等情况发生(例如TRUNCATE不能与其他命令同时操作一张表,所以TRUNCATE需要拿到ACCESS EXCLUSIVE模式锁)。
Conflicting Lock Modes
| Requested Lock/Existing Lock | ACCESS SHARE | ROW SHARE | ROW EXCL. | SHARE UPDATE EXCL. | SHARE | SHARE ROW EXCL. | EXCL. | ACCESS EXCL. |
|---|---|---|---|---|---|---|---|---|
ACCESS SHARE |
X | |||||||
ROW SHARE |
X | X | ||||||
ROW EXCL. |
X | X | X | X | ||||
SHARE UPDATE EXCL. |
X | X | X | X | X | |||
SHARE |
X | X | X | X | X | |||
SHARE ROW EXCL. |
X | X | X | X | X | X | ||
EXCL. |
X | X | X | X | X | X | X | |
ACCESS EXCL. |
X | X | X | X | X | X | X | X |
行级锁
TDSQL PG的行级锁主要用于控制对单数据行的并发访问。行级锁通常在事务中使用,以确保在事务执行期间,其他事务不能修改被锁定的行。
TDSQL PG提供了以下几种行级锁模式:
- FOR UPDATE:这种锁定模式在读取数据行时获取一个排他锁。一旦一个事务获取了这种锁,其他事务就不能获取同一行的FOR UPDATE、FOR NO KEY UPDATE、FOR SHARE 或 FOR KEY SHARE锁,直到第一个事务完成。
- FOR NO KEY UPDATE:这种锁定模式类似于FOR UPDATE,但它允许其他事务获取FOR KEY SHARE锁。这对于需要防止其他事务修改数据行,但允许它们并发读取数据行的情况很有用。
- FOR SHARE:这种锁定模式在读取数据行时获取一个共享锁。这意味着其他事务可以获取同一行的FOR SHARE或FOR KEY SHARE锁,但不能获取FOR UPDATE或FOR NO KEY UPDATE锁。
- FOR KEY SHARE:这是最轻量级的行级锁定模式。它允许其他事务获取FOR NO KEY UPDATE、FOR SHARE或FOR KEY SHARE锁。
咨询锁
咨询锁(Advisory Locks)是TDSQL PG提供的一种特殊类型的锁,它们不由系统自动管理,完全提供给应用程序使用。这种锁的主要用途是在应用程序级别实现复杂的业务规则或协调多个事务的行为。
Advisory Lock有两种级别:会话级别和事务级别。
- 会话级别的Advisory Lock:这种锁在当前会话结束时自动释放,或者可以通过调用unlock函数手动释放。
- 事务级别的Advisory Lock:这种锁在当前事务结束时自动释放,无论事务是提交还是回滚。