JPA 线程安全实体
JPA thread safe entity
我的系统中有这样减速的项目实体:
@Entity
@Table(name = "ITEMS")
@XmlRootElement
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Column(name = "VIEWS")
private Integer views;
// More fields.........
public Item() {
}
public Item(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getViews() {
return views;
}
public void setViews(Integer views) {
this.views = views;
}
// More getters and setters.......
}
在我的系统中,每个用户都可以查看该项目,但只有所有者可以编辑它。唯一的限制是所有者只有在没有其他人查看的情况下才能编辑该项目。
所以我的更新方法应该是这样的:
public void update(Integer id) {
Item item = itemFacade.find(id);
if (item == null || item.getViews() > 0) {
return;
}
// Set some fields......
itemFacade.edit(item);
}
此方法必须同步,因为存在竞争条件:当我设置字段时,其他用户查看了该项目。
但是我怎样才能防止出现这种竞争情况呢?我认为我在某处读到 JPA 在找到实体时创建实体的新实例。
所以制作 synchronized(item)
(在我检查它不为空之后)不能防止这种竞争条件,因为储物柜是不同的。
那么我该如何防止这种竞争情况呢?
解决冲突的正确答案描述here。
我的系统中有这样减速的项目实体:
@Entity
@Table(name = "ITEMS")
@XmlRootElement
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Column(name = "VIEWS")
private Integer views;
// More fields.........
public Item() {
}
public Item(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getViews() {
return views;
}
public void setViews(Integer views) {
this.views = views;
}
// More getters and setters.......
}
在我的系统中,每个用户都可以查看该项目,但只有所有者可以编辑它。唯一的限制是所有者只有在没有其他人查看的情况下才能编辑该项目。
所以我的更新方法应该是这样的:
public void update(Integer id) {
Item item = itemFacade.find(id);
if (item == null || item.getViews() > 0) {
return;
}
// Set some fields......
itemFacade.edit(item);
}
此方法必须同步,因为存在竞争条件:当我设置字段时,其他用户查看了该项目。
但是我怎样才能防止出现这种竞争情况呢?我认为我在某处读到 JPA 在找到实体时创建实体的新实例。
所以制作 synchronized(item)
(在我检查它不为空之后)不能防止这种竞争条件,因为储物柜是不同的。
那么我该如何防止这种竞争情况呢?
解决冲突的正确答案描述here。