Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
隔离级别可在postgresql上序列化的悲观写锁_Postgresql_Hibernate_Isolation Level - Fatal编程技术网

隔离级别可在postgresql上序列化的悲观写锁

隔离级别可在postgresql上序列化的悲观写锁,postgresql,hibernate,isolation-level,Postgresql,Hibernate,Isolation Level,当我使用带有可序列化隔离级别的悲观写锁时,我在某些场景中遇到了一些错误 下面是MappingEntity类: @Data @Entity(name = "asset_type_mapping") @Table( name = "asset_type_mapping", uniqueConstraints = @UniqueConstraint( name = "UQ_MappingEntity",

当我使用带有可序列化隔离级别的悲观写锁时,我在某些场景中遇到了一些错误

下面是MappingEntity类:

@Data
@Entity(name = "asset_type_mapping")
@Table(
    name = "asset_type_mapping",
    uniqueConstraints =
            @UniqueConstraint(
                name = "UQ_MappingEntity",
                columnNames = {
                    Constants.DATA_TYPE_VALUE,
                    Constants.DATA_TYPE_NAMESPACE_INDEX,
                    Constants.TENANT_ID,
                    Constants.ASSET_TYPE_NAME
                }
            )
)
public class MappingEntity {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    @Column(name = Constants.DATA_TYPE_VALUE)
    private long dataTypeValue;

    @Column(name = Constants.DATA_TYPE_NAMESPACE_INDEX)
    private int dataTypeNamespaceIndex;

    @Column(name = Constants.ASSET_TYPE_NAME)
    private String assetTypeName;

    @Column(name = Constants.TENANT_ID)
    private String tenantId;
}

下面是MappingRepository类:

public interface MappingRepository extends JpaRepository<MappingEntity, String> {

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    MappingEntity findMappingEntityWithLockByTenantIdAndAssetTypeName(
            String tenantId, String assetTypeName);
}
现在让我解释一下我的步骤。在我的数据库中,MappingEntity表中有两行,我想同时删除这两行。为此,我同时发送了两个请求。两个线程接受此请求并同时调用deleteAspectType()方法。这两个线程首先运行带锁的selectquery,然后运行delete。但其中一个线程未能删除,并引发异常:

ERROR: could not serialize access due to read/write dependencies among transactions
  Detail: Reason code: Canceled on identification as a pivot, during write.
  Hint: The transaction might succeed if retried.
我很困惑。线程检索不同的行并锁定它们。 当我切换到隔离级别以读取Committed时,我不接受此异常,并且工作正常。或者,当我在isolatation级别仍然可以序列化的情况下,使用tenantId和assetTypeName添加到这个表的索引时,我也不会接受这个异常


请有人给我解释一下,为什么在隔离级别可序列化而不使用索引时会出现此异常?为什么在隔离级别读取已提交或隔离级别可序列化而使用索引时此代码工作正常?

此行为可能是由以下事实解释的:如果使用索引或使用表顺序扫描,则事务不会读取相同的行。说

为了保证真正的可序列化性,PostgreSQL使用谓词锁定, 这意味着它保持锁,允许它确定 写操作会对以前从数据库读取的结果产生影响 并发事务,首先运行它。在PostgreSQL中,这些锁 不会造成任何阻塞,因此不能在导致阻塞的过程中发挥任何作用 僵局。它们用于标识和标记各个组件之间的依赖关系 并发可序列化事务,在某些组合中可以 导致序列化异常

以及:

顺序扫描总是需要一个关系级别 谓词锁。这可能会导致序列化速率增加 失败。鼓励用户使用索引扫描可能会有所帮助 降低随机页面成本和/或增加cpu元组成本。一定要 权衡事务回滚的任何减少,并根据任何 查询执行时间的总体变化


这种行为可能是由这样一个事实解释的:如果使用索引或使用表顺序扫描,则事务不会读取相同的行。说

为了保证真正的可序列化性,PostgreSQL使用谓词锁定, 这意味着它保持锁,允许它确定 写操作会对以前从数据库读取的结果产生影响 并发事务,首先运行它。在PostgreSQL中,这些锁 不会造成任何阻塞,因此不能在导致阻塞的过程中发挥任何作用 僵局。它们用于标识和标记各个组件之间的依赖关系 并发可序列化事务,在某些组合中可以 导致序列化异常

以及:

顺序扫描总是需要一个关系级别 谓词锁。这可能会导致序列化速率增加 失败。鼓励用户使用索引扫描可能会有所帮助 降低随机页面成本和/或增加cpu元组成本。一定要 权衡事务回滚的任何减少,并根据任何 查询执行时间的总体变化

ERROR: could not serialize access due to read/write dependencies among transactions
  Detail: Reason code: Canceled on identification as a pivot, during write.
  Hint: The transaction might succeed if retried.