Optimistic Lock and Pessimistic Lock of Hibernate

Optimistic Lock and Pessimistic Lock of Hibernate

Hibernate乐观锁和悲观锁Locking

只要说到乐观锁和悲观锁,这里的锁不是数据库的机制,而是一种编程机制,为防止出现刚刚被另一个事务提交的数据又被这一个重复提交,重复修改。在后一个(每一个)事务提交的时候,它需要看一下当前数据库的数据是不是跟自己修改前一样。乐观锁和悲观锁不止Hibernate有Java有,别的语言一样有。

Optimistic 乐观锁

乐观锁假设多事务可以在不影响互相影响的情况下独自完成,并且因此事务可以在不锁资源的情况下处理数据。在提交之前,每一个事务需要验证没有其他事务修改过当前数据。如果检查出冲突,这次事务就会被回滚。并且可以被重新启动来检查是否仍然满足条件,需要继续执行。(Hibernate JBoss中只提到回滚,但是加了个wikipedia链接,wikipedia提到会事务可以重启,stackoverflow提到事务会被重启。)

Pessimistic 悲观锁

悲观锁假设并发事务直接会发生冲突,并且要求资源在读后必须被锁,直到处理完成事务结束。

乐观锁详细说明

在应用中使用长的事务或者会话,可能跨越好几个事务,这时可以使用带version的数据,如果相同的数据被两个会话更新,后边提交的那个就会被通知冲突,并且不会覆盖之前的提交。这个方法保证了一定的隔离,在Read-Often Write-Sometimes情况下,运行非常好。

Hibernate 提供了两种不同的机制存储version信息,一种是用数字,一种使用时间戳。

Number

@Version annotation

@Entity
public class Flight implements Serializable {  
...
    @Version
    @Column(name="OPTLOCK")
    public Integer getVersion() { ... }
}

hbm.xml

<version  
        column="version_column"
        name="propertyName"
        type="typename"
        access="field|property|ClassName"
        unsaved-value="null|negative|undefined"
        generated="never|always"
        insert="true|false"
        node="element-name|@attribute-name|element/@attribute|."
/>
Timestamp

Date 使用 Version会被hibernate自动处理。

@Entity
public class Flight implements Serializable {  
...
    @Version
    public Date getLastUpdate() { ... }
}
<timestamp  
        column="timestamp_column"
        name="propertyName"
        access="field|property|ClassName"
        unsaved-value="null|undefined"
        source="vm|db"
        generated="never|always"
        node="element-name|@attribute-name|element/@attribute|."
/>
悲观锁详细说明

一般的,你只需要在JDBC connections 指定数据库的隔离级别并且让数据库处理锁问题。如果确实需要排他悲观锁或者在一个新事务重新获取锁,hibernate准备了工具。

。。。

Related Article