悲观锁:简单的理解就是把需要的数据全部加锁,在事务提交之前,这些数据全部不可读取和修改。
乐观锁:使用对数据进行版本校验和比较,来对保证本次的更新时最新的,否则就失败。
——乐观锁 通过JPA 表中加入 @Version
JPA通过在实体类(POJO)中使用@Version注解来发现数据库记录的并发操作。当JPA运行时检测到一个并发操作也在试图更改同一条记录。它会抛出一个尝试提交的事务异常。
下面是一个带有@Version注解字段的类:
- @Entity
- public class MyEntity implements Serializable {
- @Id
- @GeneratedValue
- private Long id;
- private String name;
- @Version
- private Long version;
- }
如果要修改该实体类的数据。带有注解@Version的version字段将会自增,就像下面的sql语句:
- UPDATE MYENTITY SET …, VERSION = VERSION + 1 WHERE ((ID = ?) AND (VERSION = ?))
如果WHERE子句不能匹配记录(因为相同的实体已经被另一个线程更新),那么持久性提供者将抛出OptimisticLockException。
这将防止创建两个一样的实体类实例。
—————————————————————————————————————————————————————————————————————
悲观锁的做法:
select * from user where uid=1 for update;
update user set name='bac' where uid=1;
这样,uid为1的这行记录,就被锁住,在事务提交之前,他不可被其他事务读取和修改。