Hibernate框架簡介③

Milky-way發表於2018-08-10

資料庫的事務的隔離級別:

序列化讀(Serializable): 級別最高, 最安全, 但效率最低, A事務沒有提交或回滾之前, 其他事務不能操作A正在操作的資料

不可提交讀(read-uncommitted): 簡單理解就是事務在沒有提交的情況下讀取資料.

    髒讀: A事務讀取資料時, B事務在修改資料但還沒提交, A事務再次讀取該資料時能夠讀取到B事務修改的資料

    不可重複讀: 由於可以髒讀, 還是髒讀的情景下, 意味著可以不可重複讀, 因為兩次讀取到的資料都不一樣(不重複)

    幻讀: 事務A讀取到了10條資料, 此時事務B又插入了10條資料但還沒提交, 但事務A重新讀取時讀取到的是20條資料, 則為幻讀

可提交讀(read-committed): 簡單理解就是事務在已經提交的情況下的讀取資料情況, 該隔離級別是Oracle的預設隔離級別

    髒讀: 事務A在運算元據, 此時事務B此時修改了資料如果沒有提交, 事務A無法讀取到事務B所修改的資料, 此為不可髒讀

    不可重複讀: 事務A在讀取資料時, 事務B做了修改並提交, 此時事務A再次讀取資料時是事務B修改後的資料, 此為不可重複讀

    幻讀: 事務A在讀取了10條資料, 事務B又插入了10條資料並提交, 此時事務A再次讀取資料時發現是20條資料, 此為幻讀

可重複讀(repeatable-read): 簡單理解為重複讀取資料(該隔離級別是Mysql的預設隔離級別)

    髒讀: 事務A讀取資料後, 但事務A沒有結束(提交或回滾), 那麼此時事務B修改資料後不管是否提交, 事務A都無法讀取到事務B所修改的資料, 此為不可髒讀

    不可重複讀: 同髒讀, 事務A是重複讀的型別的, 此為不能"不可重複讀"

    幻讀: 無法避免幻讀, 事務A讀取了10條資料, 事務B插入了10條資料並提交, 此時事務A能夠查詢到20條資料

 

查詢mysql資料庫的隔離級別的查詢語句, "@@global.tx_isolation" 為全域性, "@@tx_isolation" 為每次連線的隔離級別

select @@ global.tx_isolation, @@tx_isolation

 

修改mysql資料庫的隔離級別:

set global tx_isolation = 'read-uncommitted';

set tx_isolation = 'read-uncommitted';

 

session的flush

測試程式碼:

package com.rl.hiber.test;

import java.util.Date;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.rl.hiber.model.User;
import com.rl.hiber.utils.HibernateUtil;

public class TestHibernate {

    @Test
    public void test1() {
        
        Session session = HibernateUtil.getSessoion();
        Transaction tx = session.beginTransaction();
        User user = new User();
        try {
            user.setUname("王五");
            user.setGender(1);
            user.setBirthday(new Date());
            //uuid的主鍵生成策略, 有session生成, 把user物件儲存在session臨時儲存區和持久區(在持久區把dirty變成true)
            session.save(user);
            //發出sql語句, 清理臨時儲存區, 把dirty變成false(Hibernate認為只要執行了flush就不是髒資料)
            //至於資料庫可不可見是由資料庫的隔離級別來決定的
            session.flush();
            tx.commit();
        } catch (HibernateException e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            HibernateUtil.closeResource(session);
        }
    }
}

利用flush完成大量資料的入庫:

測試程式碼:

package com.rl.hiber.test;

import java.util.Date;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.rl.hiber.model.User;
import com.rl.hiber.utils.HibernateUtil;

public class TestHibernate {

    
    
    @Test
    public void test2() {
      
        Session session = HibernateUtil.getSessoion();
        Transaction tx = session.beginTransaction();
        try {
            for(int i = 0; i < 100009; i++) {
                User user = new User();
                user.setUname("zhangsan"+i);
                user.setGender(1);
                user.setBirthday(new Date());
                session.save(user);
                if(i%100 == 0) {
                    session.flush();//每向session中存入100條資料則flush一次
                }
            }
            session.flush();//最後也要flush一次, 防止剩下的不滿100條
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            HibernateUtil.closeResource(session);
        }
    }
}

資料庫結果:

相關文章