数据库基础
来源:互联网 发布:在mac上拖拽文件 编辑:程序博客网 时间:2024/04/29 13:59
一.数据库事物特征
1.Atomic(原子性)
不可分割
2.Consistency(一致性)
参照完整
3.Isolation(隔离性)
防止并发
4.Durability(持久性)
永久保存数据
二.事物和并发
1.并发问题:第一类丢失,脏读,虚读,不可重复读,第二类丢失更新(不可重复读的特例)
2.锁的类型(数据库系统中的):共享锁(select 是使用),独占锁(insert update delete等),更新锁(为解决死锁)
3.事物隔离级别:
序列化(Serializable):代码:8
可重复读(Repeatable Read):代码:4
读已提交的数据(Read Commited):代码:2 //会产生第二类数据丢失 和 不可重复读
读为提交的数据(Read Uncommited):代码:1
4.设置隔离级别
MySql:
MySql->set transaction isolation level read commited
eg:hibernate.connection.isolation=2
三.悲观锁 和 乐观锁 (针对Read Commited)
1.悲观锁:操作数据,假定有其他事物来竞争
SQL:
select * from user where id=1 for update
Hibernate中使用:
get()/load() 使用
User user = (User)session.get(User.class,1,LockMode.UPGRDE);
Query 使用
query.setLockMode("",LockMode.UPDATE);
锁定模式:
LockMode.NONE //有缓存用缓存,没有从数据库
LockMode.READ //直接从数据库,不使用缓存
LockMode.UPGRADE //相当于SQL:select form update ->独占锁
LockMode.UPGRADE_NOWAIT //是Oracle数据库特有的 select for update nowait
LockMode.WAITE //insert update 数据时候,Hibernate 内部使用的
LockMode.FORCE //在数据库中强制增加对象的版本,本来表明它已经被当前事物修改
备注:如果数据库不支持select ...for update ->实现:在表中设置一列标志位,表示此表是锁定的还是空闲的,如:此标志位true是我等 待,false时我可以操作.每个操作前都锁定(设标志为true) 操作后解锁(设置标志位false);
2.乐观锁:操作数据,假定没有其他竞争
实现:
版本控制version(推荐使用此方式)
时间戳timestamp(不推荐)
使用前准备:version -> tb_user 加一列versionId (int) User Entity 加一属性versionId (int) ,有get 和 set
timestamp -> versionId 变为Date型的,其他和version一样.
<hibernate-mapping package="com.pannuo.entity">
<class name="User" table="tb_user">
<id name="userId" column="userId" type="int">
<generator class="increment"/>
</id>
<version name="versionId" coulmn="versionId"/> //必须紧跟在<id> 后,<property> 前
<timestamp name="versionDate" coulmn="versionDate"/>
</hibernate-mapping>
其他实现方式:Class 元素 optimistic-lock="all/dirty" dynamic-update="true"
使用optimistic-lock时,dynamic-update必须设置为true
all : update where 字句中包含所有属性
dirty:update where 字句中包含改变过的属性