数据库的事务的隔离级别:
序列化读(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);
}
}
}
数据库结果: