1)引入
factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
Transaction tx = session.beginTransaction();
User user = (User) session.get(User.class, 1);
System.out.println(user.getName());
System.out.println("下断点,去数据库修改name");
session.refresh(user);
System.out.println(user.getName());
tx.commit();<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"></span> 修改前数据库内容:
下断点之后,修改数据库内容并提交事务:
修改完之后直接refresh刷新,从数据库中取出新的数据
结果为:
Hibernate: select user0_.id as id1_7_0_, user0_.name as name2_7_0_ from t_user user0_ where user0_.id=?
xx
下断点,去数据库修改name
Hibernate: select user0_.id as id1_7_0_, user0_.name as name2_7_0_ from t_user user0_ where user0_.id=?
xx 说明对数据库的修改根本没有影响到取出的数据
2) 原因
过程涉及到两个事务,一个是代码中获取数据,一个是直接从数据库直接修改数据
这就涉及到事务隔离级别的问题:
1> 读未提交:也就是另外的事务对数据只是修改了还没有提交,其他事务就可以读出来了(因为很有可能不提交了或回滚,所以会读出脏数据)
2> 读已提交:也就是另外的事务对数据修改而且提交了,另外的事务就可以读到
3> 可重复读:一个事务开始的时候,会创建一个对数据库的视图,保存了开始时数据库中数据的状态,这样即使其他事务修改了数据,本事务也读取不到改变
4> 串行化(不可并发):也就是所有事务只能一个个来,不能并发执行
mysql、Hibernate默认的事务隔离级别都是可重复读
3)在Hibernate中修改隔离级别
<property name="connection.isolation">2</property> 在Hibernate中:read uncommitted ——1 read commited——2 repeatable read ——4 不可并发——8
结果为:
Hibernate: select user0_.id as id1_7_0_, user0_.name as name2_7_0_ from t_user user0_ where user0_.id=?
xx
下断点,去数据库修改name
Hibernate: select user0_.id as id1_7_0_, user0_.name as name2_7_0_ from t_user user0_ where user0_.id=?
zz 4)当然也可以在数据库中修改隔离级别
本文详细解析了Hibernate中事务隔离的概念及默认的可重复读隔离级别,并展示了如何通过配置改变隔离级别以解决数据库修改影响到缓存数据的问题。通过实践示例,演示了在不同隔离级别下的数据读取行为,最终提供了修改隔离级别的方法。
913

被折叠的 条评论
为什么被折叠?



