在 PostgreSQL 中,您可以通过使用表级锁来测试这一点,以确保竞争事务同时运行。设置:
CREATE TABLE place (id serial primary key, state_code integer, type text);
INSERT INTO place (state_code, type) VALUES (5, 'town'), (6, 'town');
然后在会话 T0 中:
BEGIN; LOCK TABLE place;
在两个新会话中,发出 T1 和 T2 的命令。
现在回到 T0 问题:
ROLLBACK;
释放表级锁并允许 T1 和 T2 竞争。
隔离(默认)两者都将被转置......尽管在READ COMMITTED
现实世界中这将取决于交易的确切顺序并且不能依赖。
在REPEATABLE READ
, 中(在 PostgreSQL 9.0 中称为SERIALIZABLE
隔离),它们都将被转置,与 with 相同的警告,READ COMMITTED
因为两者对于单语句事务本质上是等效的;快照是在运行第一条语句时拍摄的,而不是在BEGIN
.
SERIALIZABLE
孤立地,通过 GUC 或 设置,default_transaction_isolation
一个BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE
事务将无法提交并出现序列化失败,而另一个事务将成功,导致所有行有state_code
5,或所有行有state_code
6,具体取决于哪个事务获胜。
如果 SQL Server 也中止了其中一个事务,那么它正在执行正确的序列化。
SQL Server 遵循正确的序列化(当要求严格序列化时,就像当前版本的 PostgreSQL 一样),而 PostgreSQL 的测试版本设置为READ COMMITTED
隔离(不应该序列化)或 9.1 之前的SERIALIZABLE
隔离(无法检测到此异常)并且不遵守严格的事务序列化语义。
如果default_transaction_isolation
设置为除 之外的任何内容,则在 PostgreSQL 9.2 中可能会遇到这种情况SERIALIZABLE
,并且是 PostgreSQL 9.1 之前的规范。
看起来 SQL Server 使用SET TRANSACTION ISOLATION LEVEL
. 在 PostgreSQL 中,您使用default_transaction_isolation
GUC或SET TRANSACTION ISOLATION LEVEL
. 尚不清楚 SQL Server 是否允许您在全局范围内设置默认事务隔离级别。