事务
1.事务特性:ACID
- 原子性:整体
- 一致性:数据
- 隔离性:并发
- 持久性:结果
2.隔离问题:
- 脏读:一个事务读到另一个事务没哟提交数据
- 不可重复读:一个事务读到另一个事务已经提交数据(update)
- 幻读(虚读):一个事务读到另一个事务已经提交数据(insert)
3.隔离级别:
- 读未提交:read uncommitted, 一个事务读到另一个事务没哟提交数据。存在3个问题
- 读已提交:read committed,一个事务读到另一个事务已经提交数据。解决:脏读;存在2个问题
- 可重复读:repeatable read,一个事务读到数据一直重复。解决:脏读、不可重复读;存在1个问题
- 串行化:serializable,单事务
hibernate隔离级别:
在hibernate.cfg.xml中配置: hibernate.connection.isolation = 4
lost upload 丢失更新
- 悲观锁:丢失更新问题肯定发生。
使用数据库锁机制,mysql数据库锁 - 读锁:共享锁,多个事务可以同时操作。
select ... lock in share mode - 写锁:排他锁,独占,每一次只能由一个事务进行操作。
select ... for update
注意:数据库的锁必须在事务中使用。 - 乐观锁:丢失更新肯定不发生
在表中添加一个字段,用于记录操作版本,如果版本不一致,将不允许提交。
hibernate操作:
- 乐观锁 :
<version name="属性"> 类型必须整形,hibernate自动维护数据累加<timestamp name=""> 类型 java.sql.Timestamp ,只要操作,数据库默认使用自动当前时间。
<class optimistic-lock="all" > 以所有的字段版本控制 -
悲观锁: session.get(Class,OID, LockMode. UPGRADE)
管理session
1.api操作
- factory.openSession() 开发一个新的回话
- factory.getCurrentSession() 获得当前线程中绑定的session
2.hibernate session管理配置
- ThreadLocal 线程本地变量,在一个线程中共享数据。
Thread.currentThread() 获得当前线程
ThreadLocal 底层使用Map<Thread,Object>
map.key : 当前线程
map.value :在当前线程需要共享数据 - api
get() -- map.get(当前线程)
set(value) -- map.put(当前线程, value)
remove() -- map.remove(当前线程)