一、5类事物并发问题
二、事物的隔离级别
三、处理第一类丢失更新和第二类丢失更新--使用锁机制
数据库的锁机制:
在MYSQL中 ,为了避免第二类丢失更新出现,提供了悲观锁的机制;
SELECT XXX FROM XXX FOR UPDATE;
SELECT FOR UPDATE就是在数据上添加一个共享锁的东西;
1,共享锁允许其他普通的SELECT语句执行;
2,共享锁排斥其他的SELECT FOR UPDATE;
3,共享锁排斥INSERT DELETE等DML;
在hibernate中使用悲观锁:
1,session1.createQuery("").setLockOptions(LockOptions.UPGRADE);
2,Account a=(Account)session1.get(Account.class,1L,LockOptions.UPGRADE);
3,Account a=(Account)session1.load(Account.class,1L,LockOptions.UPGRADE);
注意,
使用悲观锁会在一定情况下降低系统的并发性能;
如果系统对数据安全的要求非常高,请使用悲观锁;
乐观锁:
在hibernate中使用乐观锁:
1,在对象中添加一个private int version属性,最好把setter/getter设置为private;
2,在映射文件中添加:
四、例子
@Setter
@Getter
public class Account implements Serializable {
private Long id;
private int vesion;
private Double balance;
}
配置文件
<hibernate-mapping package="com.shenzhenair.day03.Transactions" >
<class name="Account">
<id name="id" >
<generator class="native"/>
</id>
<property name="vesion" />
<property name="balance" />
</class>
</hibernate-mapping>
测试用例:
@Test
public void testTransaction(){
Session session1 = HibernateUtils.openSession();
session1.beginTransaction();
Session session2 = HibernateUtils.openSession();
session2.beginTransaction();
Account a = (Account) session1.get(Account.class,1L);
Account b = (Account) session2.get(Account.class,1L);
a.setBalance(a.getBalance() - 5000);
b.setBalance(b.getBalance() + 5000);
try {
session2.getTransaction().commit();
session1.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
System.out.println("请稍后再进行操作!");
}
session2.close();
session1.close();
}