一、事务的并发问题
数据库是要被n多个用户共同访问的,在多个事务同时使用相同的数据时,可能会发生并发的问题,具体为:
- 脏读:一个事务读取到另一个事务未提交的数据。
- 不可重复读:一个事务对同一行数据重复读取两次,但是得到了不同的结果。
- 虚读(幻读):一个事务连续两次在数据库进行同样条件的查询,但是第二次查询结果包含了第一次查询中未出现的数据。(注意与不可重复读的区别)
二、事务的隔离级别
1、读未提交(1级,效率高 但安全性低):当一个事务进行写(更新)数据,则另外一个事务不允许同时进行写(更新)数据,但允许其他事务进行读数据,即使是未提交的 (但这个不能防止脏读)
更新丢失是因为一个事务开始进行写事务,另一个事务也可以进行写事务导致的。
2、读已提交(2级,可防止脏读):读取数据的事务允许其他事务继续读取该数据,但是未提交的写事务将会禁止其他事务访问改行。
脏读是由于读到未提及的数据
3、可重复读(4级,可防止不可重复读、脏读):读取数据的事务禁止写事务,写事务将禁止其他任何事务。
不可重复读是一个事务对一行数据重复读取两次,但是得到不同的结果;
脏读是读到未提交的数据
4、序列化(也称串行化,8级,防止一切并发问题但是效率低):提供严格的事务隔离。事务只能一个接着一个执行,不能并发执行
简单总结:
事务并发问题:
(1)脏读
(2)不可重复读
(3)虚读
(4)更新丢失
事务隔离级别:
(1)读未提交
(2)读已提交
(3)可重复读
(4)序列化(串行化)
三、总结:
事务应该在Service层开启和提交或者回滚
事务的开启需要 session
获得session 有两种方式; opensession 每次打开都是一个新的
getCurrentSession 线程绑定的session
Service层有session
Dao层也有session 这两个session必须保证是同一个session这样事务的提交才能起作用。
Hibernate框架中所有增删改,都必须提交事务才能最终修改到数据库 所以在增删改操作中必须使用getCurrentSession 。
使用currentSession必须在配置文件中加入属性
<property name="hibernate.current_session_context_class">thread</property>