Hibernate 乐观锁和悲观锁处理事物并发问题

一、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();

    }

猜你喜欢

转载自blog.csdn.net/m0_38068812/article/details/83960292