删除在多对一关系中永远卡住的呼叫
delete call stuck for forever in a Many to One Relationship
正在尝试 运行 删除多对一关系的查询。但有时当删除行的计数超过 ~50 时,它会卡住一段时间。
存储库:
@Repository
public interface TransitItemRepository extends JpaRepository<TransitItemsMapping, UUID> {
@Modifying
@Transactional
@Query(value="delete from TransitItemsMapping t where t.grouping_form_id=:groupingFormId",nativeQuery = true)
void deleteByGroupingFormId(@Param("groupingFormId") UUID groupingFormId);
}
域:TransitItemsMapping.java
@Data
@Entity
@Table(name = "TransitItemsMapping")
public class TransitItemsMapping implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
@Column(name = "transit_Item_id",unique = true, nullable = false)
private UUID transitItemId;
@ToString.Exclude
@JsonManagedReference
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "grouping_form_id")
//@OnDelete(action = OnDeleteAction.CASCADE)
private GroupingForm groupingForm;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(referencedColumnName = "dim_Item_ID",name = "item_id")
private Item item;
@Column(name ="item_relationship_id", insertable = false,updatable = false)
private String itemRelationshipId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_relationship_id",referencedColumnName = "dim_item_relationship_id")
private VendorFactoryItem vendorFactoryItem;
@Column(name = "edam_id")
private String edamId;
@Column(name = "model_number")
private String modelNumber;
@Column(name = "description")
private String description;
@Column(name = "packaging_details")
private String packagingDetails;
@Column(name = "packaging_method")
private String packagingMethod;
@Column(name = "is_side_stack")
private String isSideStack;
@Column(name = "quantity")
private Integer quantity;
@Column(name = "dimensions")
private String dimensions;
@Column(name = "product_net_weight")
private String productNetWeight;
@Column(name = "plastic_bag_ind")
private String plasticBagInd;
@Column(name = "insertion_order")
private Integer insertionOrder;
@Column(name = "comments")
private String comments;
@Column(name = "item_unique_id")
private String itemUniqueId;
@Column(name = "itm_pak_qty")
private Integer itemPackQuantity;
}
GroupingForm.java
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Entity
@Table(name = "GroupingForm")
public class GroupingForm implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
@Column(name = "grouping_form_id",unique = true, nullable = false)
private UUID groupingFormId;
@Column(name = "grouping_form_name")
private String groupingFormName;
@Column(name = "vid")
private String vid;
@Column(name = "vendor_name")
private String vendorName;
@Column(name = "hovbu")
private String hovbu;
@Column(name = "fid")
private String fid;
@Column(name = "factory_name")
private String factoryName;
@Column(name = "item_count")
private Integer itemCount;
@CreationTimestamp
@Column(name = "creation_date")
private Timestamp creationDate;
@Column(name = "created_by")
private String createdBy;
@UpdateTimestamp
@Column(name = "modified_date")
private Timestamp modifiedDate;
@Column(name = "modified_by")
private String modifiedBy;
@Column(name = "product_engineer")
private String productEngineer;
@Column(name = "status")
private String status;
@Column(name = "sourcing_type")
private String sourcingType;
@Column(name = "total_comments")
private Integer totalComments;
@Column(name = "factory_name_chinese")
private String factoryNameChinese;
@Column(name = "grouping_form_type")
private String groupingFormType;//to save as Product/transit/Product_transit
@Column(name = "ref_id")
private String refId;
@JsonBackReference
@OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<ProductItemsMapping> productItems = new ArrayList<>();
@JsonBackReference
@OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<TransitItemsMapping> transitItems = new ArrayList<>();
@Column(name = "pdf_status")
private String pdfStatus;
public GroupingForm(UUID groupingFormId,String groupingFormName, String vid, String vendorName, String hovbu,
String fid, String factoryName, String status, String sourcingType, Integer totalComments,
Date creationDate, String createdBy, Date modifiedDate, String modifiedBy, String productEngineer,
Integer itemCount, String groupingFormType, String refId, String factoryNameChinese) {
this.groupingFormId = groupingFormId;
this.groupingFormName = groupingFormName;
this.vid = vid;
this.vendorName = vendorName;
this.hovbu = hovbu;
this.fid = fid;
this.factoryName = factoryName;
this.status = status;
this.sourcingType = sourcingType;
this.totalComments = totalComments;
this.creationDate = creationDate!=null?new Timestamp(creationDate.getTime()):null;
this.createdBy = createdBy;
this.modifiedDate = modifiedDate!=null?new Timestamp(modifiedDate.getTime()):null;
this.modifiedBy = modifiedBy;
this.productEngineer = productEngineer;
this.itemCount = itemCount;
this.groupingFormType = groupingFormType;
this.refId = refId;
this.factoryNameChinese = factoryNameChinese;
}
}
服务:已经用@Transactional 注释的方法
private void updateTransitItem(GroupingCardsDto groupingCardsDto, GroupingForm groupingForm) {
transitItemRepository.deleteByGroupingFormId(groupingCardsDto.getGroupingFormDto().getGroupingFormId());
groupingFormService.saveTransitItems(groupingCardsDto.getGroupingFormDto(), groupingForm);
}
当我在调试模式下 运行ning eclipse 时,我的断点被卡在 delete 方法中。我在用
x86_64-pc-linux-gnu 上的 PostgreSQL 9.6.24,由 Debian clang 版本 12.0.1 编译,64 位
版本,以及池连接 Hikari-CP-3.2.0.
而且如果我在长时间(~45 分钟)后让我的调试 运行ning,我会遇到错误。
marked as broken because of SQLSTATE(08006), ErrorCode(0)\norg.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
提前致谢。
这可能有两个原因。
您的 delete 语句实际上花费了很长时间,或者卡在了锁上。
45 分钟,对于简单的删除来说肯定很长,而且只有在处理大量数据(例如数百万行)时才可以预期。使用解释计划来验证是否使用了预期的索引。
我认为锁更可能是问题的原因。您需要检查存在哪些锁以及它们来自何处。 This wiki page about lock monitoring in PostgreSQL 似乎是个不错的起点。
正在尝试 运行 删除多对一关系的查询。但有时当删除行的计数超过 ~50 时,它会卡住一段时间。
存储库:
@Repository
public interface TransitItemRepository extends JpaRepository<TransitItemsMapping, UUID> {
@Modifying
@Transactional
@Query(value="delete from TransitItemsMapping t where t.grouping_form_id=:groupingFormId",nativeQuery = true)
void deleteByGroupingFormId(@Param("groupingFormId") UUID groupingFormId);
}
域:TransitItemsMapping.java
@Data
@Entity
@Table(name = "TransitItemsMapping")
public class TransitItemsMapping implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
@Column(name = "transit_Item_id",unique = true, nullable = false)
private UUID transitItemId;
@ToString.Exclude
@JsonManagedReference
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "grouping_form_id")
//@OnDelete(action = OnDeleteAction.CASCADE)
private GroupingForm groupingForm;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(referencedColumnName = "dim_Item_ID",name = "item_id")
private Item item;
@Column(name ="item_relationship_id", insertable = false,updatable = false)
private String itemRelationshipId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_relationship_id",referencedColumnName = "dim_item_relationship_id")
private VendorFactoryItem vendorFactoryItem;
@Column(name = "edam_id")
private String edamId;
@Column(name = "model_number")
private String modelNumber;
@Column(name = "description")
private String description;
@Column(name = "packaging_details")
private String packagingDetails;
@Column(name = "packaging_method")
private String packagingMethod;
@Column(name = "is_side_stack")
private String isSideStack;
@Column(name = "quantity")
private Integer quantity;
@Column(name = "dimensions")
private String dimensions;
@Column(name = "product_net_weight")
private String productNetWeight;
@Column(name = "plastic_bag_ind")
private String plasticBagInd;
@Column(name = "insertion_order")
private Integer insertionOrder;
@Column(name = "comments")
private String comments;
@Column(name = "item_unique_id")
private String itemUniqueId;
@Column(name = "itm_pak_qty")
private Integer itemPackQuantity;
}
GroupingForm.java
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Entity
@Table(name = "GroupingForm")
public class GroupingForm implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
@Column(name = "grouping_form_id",unique = true, nullable = false)
private UUID groupingFormId;
@Column(name = "grouping_form_name")
private String groupingFormName;
@Column(name = "vid")
private String vid;
@Column(name = "vendor_name")
private String vendorName;
@Column(name = "hovbu")
private String hovbu;
@Column(name = "fid")
private String fid;
@Column(name = "factory_name")
private String factoryName;
@Column(name = "item_count")
private Integer itemCount;
@CreationTimestamp
@Column(name = "creation_date")
private Timestamp creationDate;
@Column(name = "created_by")
private String createdBy;
@UpdateTimestamp
@Column(name = "modified_date")
private Timestamp modifiedDate;
@Column(name = "modified_by")
private String modifiedBy;
@Column(name = "product_engineer")
private String productEngineer;
@Column(name = "status")
private String status;
@Column(name = "sourcing_type")
private String sourcingType;
@Column(name = "total_comments")
private Integer totalComments;
@Column(name = "factory_name_chinese")
private String factoryNameChinese;
@Column(name = "grouping_form_type")
private String groupingFormType;//to save as Product/transit/Product_transit
@Column(name = "ref_id")
private String refId;
@JsonBackReference
@OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<ProductItemsMapping> productItems = new ArrayList<>();
@JsonBackReference
@OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<TransitItemsMapping> transitItems = new ArrayList<>();
@Column(name = "pdf_status")
private String pdfStatus;
public GroupingForm(UUID groupingFormId,String groupingFormName, String vid, String vendorName, String hovbu,
String fid, String factoryName, String status, String sourcingType, Integer totalComments,
Date creationDate, String createdBy, Date modifiedDate, String modifiedBy, String productEngineer,
Integer itemCount, String groupingFormType, String refId, String factoryNameChinese) {
this.groupingFormId = groupingFormId;
this.groupingFormName = groupingFormName;
this.vid = vid;
this.vendorName = vendorName;
this.hovbu = hovbu;
this.fid = fid;
this.factoryName = factoryName;
this.status = status;
this.sourcingType = sourcingType;
this.totalComments = totalComments;
this.creationDate = creationDate!=null?new Timestamp(creationDate.getTime()):null;
this.createdBy = createdBy;
this.modifiedDate = modifiedDate!=null?new Timestamp(modifiedDate.getTime()):null;
this.modifiedBy = modifiedBy;
this.productEngineer = productEngineer;
this.itemCount = itemCount;
this.groupingFormType = groupingFormType;
this.refId = refId;
this.factoryNameChinese = factoryNameChinese;
}
}
服务:已经用@Transactional 注释的方法
private void updateTransitItem(GroupingCardsDto groupingCardsDto, GroupingForm groupingForm) {
transitItemRepository.deleteByGroupingFormId(groupingCardsDto.getGroupingFormDto().getGroupingFormId());
groupingFormService.saveTransitItems(groupingCardsDto.getGroupingFormDto(), groupingForm);
}
当我在调试模式下 运行ning eclipse 时,我的断点被卡在 delete 方法中。我在用 x86_64-pc-linux-gnu 上的 PostgreSQL 9.6.24,由 Debian clang 版本 12.0.1 编译,64 位 版本,以及池连接 Hikari-CP-3.2.0.
而且如果我在长时间(~45 分钟)后让我的调试 运行ning,我会遇到错误。
marked as broken because of SQLSTATE(08006), ErrorCode(0)\norg.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
提前致谢。
这可能有两个原因。
您的 delete 语句实际上花费了很长时间,或者卡在了锁上。
45 分钟,对于简单的删除来说肯定很长,而且只有在处理大量数据(例如数百万行)时才可以预期。使用解释计划来验证是否使用了预期的索引。
我认为锁更可能是问题的原因。您需要检查存在哪些锁以及它们来自何处。 This wiki page about lock monitoring in PostgreSQL 似乎是个不错的起点。