数据库基础

来源:互联网 发布:在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 字句中包含改变过的属性