📄 缓存及事务.txt
字号:
事务的四大属性:
1、原子性:要么全成功,要么全失败
2、持久性:持久化到数据库中
3、一致性:一个业务相关的处理全部执行到。
4、隔离性:事务之间不影响
没有隔离性出现的问题:
1、脏读:事务1修改休眠,事务2将事务1修改后的值取出处理后提交到数据库中。
事务1
update buy set amount=amount+100 where buyID=1;
sleep(1000);
rollback;
事务2
update buy set amount=amount+100 where buyID=1;
commit;
2、覆盖更新:事务1与事务2从数据库中同时读取数据,事务1修改但没有提交时休眠了
事务2提交后,事务1提交数据,事务1将事务2的数据覆盖了。
事务1
update buy set amount=amount+100 where buyID=1;
sleep(1000);
commit;
事务2
update buy set amount=amount+100 where buyID=1;
commit;
3、不可重复读:同一个事务相同的select语句结果不一样,主要针对update。
事务1:
select * from buy;
sleep(1000);
select * from buy;
事务2
update buy set amount=amount+100 where buyID=1;
commit;
4、幻想读:同一个事务相同的select语句第一次执行时有,第二次执行时没有,反之亦然。
事务1:
select * from buy;
sleep(1000);
select * from buy;
事务2
delete from buy where buyID=1;
commit;
或
insert into buy;
commit;
数据库的隔离性:
1、读未提交:可以读取未提交的数据,不要以防止脏读及覆盖更新。
2、读已提交:是数据库默认的事务处理方式。
读取的数据是已提交的,可以防止脏读。
当修改一行并提交时,系统会将当前所在的版本也数据
对应行的版本比较,如果小于数据版本报错回退,否则提交,可以防止覆盖更新。
分类:
乐观锁:游标打开行后,对打开的所有行不加锁,另一个事务可以读,也可以
改,让系统的并发性提高,但如果游标所在的行被另一个事务修改,当前
游标所在行再去修改并提交时发现游标所在行的当前版本比数据库的版
本低,报错,回退。
悲观锁:游标打开行后,对打开的所有行加锁,另一个事务只可以读,不可以
改,能够保证当前游标所事务的修改一定成功,但让系统性能降低。
3、可重复读:将上一个select的结果保留一个副本,下一个相同的select语句
从副本中取。
4、串行化:一个事务select一个表的数据后,其余的事务只可以读,不可以增、删、改。
相当于将整个表锁定。
事务的实现
1、代码式:通过代码实现
con.setAutoCommit(false);
con.commit();
Transaction trans=session.beginTransaction();
trans.commit();
2、声明式:通过配置文件文明事务的类型。
ejb2/ejb3/spring的事务选择方式
REQUIRED(默认):有则用已有的,没有则产生一个新的。
MANDATORY:方法前必须有一个事务,否则报错。
REQUIRESNEW:不管有前面有没有事务都产生一个新事务,如果有将前一个事务暂停。
SUPPORTS:如果前面有一个事务用,没有不用。
NOT_SUPPORTED:不用事务,如果有事务就报错。
缓存的分类:
1、事务级(一级缓存):session级缓存,级存在事务内有效
2、应用级(二级缓存):sessionFactory级缓存,让sessionFactory只有一个实例,
所有的session可以共享sessionFactory中的缓存。
3、(集群)分部式(多个二级缓存):一台主机的信息发生改变要通知其它所有的主机同步数据。
其它可能将当数据删除,需要时再重新取。
也可能是将更新的数据发送给所有其它主机进行同步。
要慎用,可能没有使系统的性能提升而降了。
缓存的目的:
1、提高系统运行的效率。
缓存的原则:
1、数据必须在可接受的范围内。
2、重复查询高的数据
3、更新小或并发更新小的数据
缓存的实现:用ehcache实现
1、hibernate提供了支持缓存的接口,通过修改
hibernate.cfg.xml设置缓存。
2、将ehcache.jar拷入工程
3、要src的根目录下加入ehcache.xml说明缓存。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
</ehcache>
3、在hibernate.cfg.xml中加入两个属性
a、说明提供二级缓存驱动类
b、说明query也支持缓存
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<property name="hibernate.cache.use_query_cache">true</property>
4、在具体的hbm.xml中说明当前类使用二级缓存
<cache stage="read-only"/>
5、在执行query之前设置其支持二级缓存
query.setCacheable(true);
list与iterator的区别
1、list初始执行时只执行一个sql,利用缓存的前提是有相同的Hql
如果Hql相同,但对应的数据没有,根据主键查找对应的数据
有多少行没有在缓存这个sql就要执行多少次。如果Hql不相同
,不利用缓存。
2、iterator初始执行时先取出所有主键值,再根据主键值查找具体的
对象。所以如果没有缓存,其初次执行会执行"行数+1"个sql。
如果缓存中有,可以直接取缓存的数据不管hql相同还是不相同。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -