什么是Hibernate的并发机制?怎么去处理并发问题?
Hibernate并发机制可以从两个方面进行概况,a.首先Hibernate的Session对象是非线程安全的。对于单个请求,单个对话,单个工作单元(即单个事务或者单个线程)而言,它通常只使用一次,然后就丢弃了。如果一个Session实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用。如果在HttpSession中有Hibernate的Session的话,就可能会出现同步访问HttpSessoin。换句话说,只要用户足够快的点击浏览器的“刷新”,就会导致两个并发运行的线程使用同一个Session。b.多个事务并发访问同一块资源,可能会导致数据的脏读、幻读、不可重复读、甚至数据更新丢失。
解决方案:1.设置事务隔离级别;2.设置锁。
注1:事务隔离级别最高为串行化(Serializable),该级别中事务只能一个一个的去执行,可以有效的避免了数据的脏读、幻读、不可重复读,但执行效率很慢;其次是可重复读(Repeatable-read),该级别可避免数据的脏读、不可重复读情况的发生,但不能避免幻读,MySQL默认此种级别;然后是读已提交(Read-committed),该级别可避免数据脏读的情况发生,Oracle默认此种级别;最后是读未提交(Read-uncommitted),该级别最低,以上情况都没法儿保证其不发生。
注2:锁我知道的有两种,一是悲观锁一是乐观锁。悲观锁采用的是数据库提供的一种锁机制,如果采用了这种锁机制,那么就要在sql语句的后面添加for update子句,当事务在操作该条记录的时候,就会把这个记录锁起来,其他事务不能执行,只用当A事务提交后,锁释放了,其他事务才能执行这条记录,所以说它是非常安全的,但效率很低。乐观锁采用的是版本号的机制来解决的,它会给表结构添加一个字段version=0,默认值是0,当A事务在操作完该条记录,提交事务时,程序会先检查版本号,如果版本号相同,就可以提交事务,同时会更新版本号version=1,所以说它更适合高并发的情况。然而Hibernate总是使用数据库的锁机制,它从不在内存中锁定对象!只要为JDBC连接指定一下隔离级别,然后就让数据库去搞定一切了。如果我们要使用乐观锁,则在映射中设置<version name="version"></version>
,注意要加在<id>
的后面,否则会报错的。
Hibernate的并发机制
最新推荐文章于 2020-02-24 13:14:05 发布