事物隔离级别_悲观与乐观锁

Posted 梦回书香

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事物隔离级别_悲观与乐观锁相关的知识,希望对你有一定的参考价值。


     1.我印象中的事物
事务是一种机制,它确保多个SQL语句被当作完整的操作单元来处理,所有的操作都完成时统一提交。

 

  2.关系数据库的事务特性(ACID)

ACID:原子性: 事务是数据库的逻辑工作单位,而且必须是原子工作单位,对于修改,要么全部执行,要么全部不执行
         一致性:事务在完成时,必须是所有的数据都保持一致状态。
    隔离型: 一个事务的执行不能被其他事务所影响。事务必须是互相隔离的,防止并发读写同一个数据的情况发生
    持久性: 一个事务一旦提交,事物的操作便永久性的保存在DB中。即使此时再执行回滚操作也不能撤消所做的更改。


  3.Spring事务的隔离级别
   a.脏读(脏数据): 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,
这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,
那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

LockMode.UPGRADE_NOWAIT Oracle 支持的锁的方式

下面的代码支持锁的代码:

@Test
    public void testPessimisticLock(){
        Session session = sf.getCurrentSession();
        session.beginTransaction();
        
        Account a = (Account) session.load(Account.class, 1,LockMode.UPGRADE);//一般用 UPGRADE
        int balance = a.getBalance();
        //do some caculations
        balance -= 10;
        a.setBalance(balance);
        
        session.getTransaction().commit();
    }

 

乐观锁

package com.bjsxt.hibernate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Account {
    
    private Integer id;
    
    private int balance;

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public int getBalance() {
        return balance;
    }

    public void setBalance(int balance) {
        this.balance = balance;
    }
    
}

  保存

@Test
    public void testOptimisticLock(){
        Session session = sf.openSession();
        Session session2 = sf.openSession();
        
        session.beginTransaction();
        Account a1 = (Account) session.load(Account.class, 2);
        
        session2.beginTransaction();
        Account a2 = (Account) session2.load(Account.class, 2);
        
        a1.setBalance(900);
        a2.setBalance(1100);
        
        session.getTransaction().commit();
        System.out.println(a1.getVersion());
        
        session2.getTransaction().commit();//第二次提交时会对比 version 字段,如果值改变,则事务处理失败,回滚
        System.out.println(a2.getVersion());
        
        session.close();
        session2.close();
    }

 

   b.不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。
那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。

   c.幻觉读: 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,
这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。
那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行。


  4.Spring的事务:声明式事务 和  编程式事务
把声明式事务和编程式事务做一下对比:
a,从耦合性上来说,编程式事务耦合性较高,声明式事务耦合性较低;
b,从是否轻量级上来说,编程式事务非轻量级,声明式事务管理轻量级;
c,从实现上来说,编程式事务以代码的形式将事务写在Java类中,声明式事务以配置文件的形式将事务写在XML文件中

以上是关于事物隔离级别_悲观与乐观锁的主要内容,如果未能解决你的问题,请参考以下文章

乐观锁与悲观锁

事务的隔离级别,乐观锁,悲观锁

postgresql 有悲观锁和乐观锁吗

悲观锁和乐观锁以及事务的隔离级别

数据库乐观锁与悲观锁

数据库的隔离级别以及悲观锁和乐观锁详解