hibernate.order_updates:

Hibernate文档中提到,该配置用于在刷新一级缓存,提交UPDATE的时候,按照每类对象的主键顺序排序后再提交,可以在高并发情况下减少事务死锁的可能。这个配置默认为false,但是非常建议在可能存在高并发情况下开启,因为其实按照类型ID排序(在内存中),并不会消耗过多性能。那么这个配置到底什么含义呢?做个简单的测试。

首先准备一个对象User,完成映射(略),完成下面的测试:

  @Before
   public void save(){
   Session session=sf.openSession();
   session.beginTransaction();
   for(int i=0;i<10;i++){
   User u=new User();
   u.setName(Math.random()+"");
   session.save(u);
   }
   session.getTransaction().commit();
   session.close();
   }

首先任意的保存10个对象,然后模拟高并发修改:

  @Test
   public void testUpdate() throws Exception{
   for(int i=0;i<10;i++){
   Thread t=new Thread(new Runnable() {
   Random random=new Random();
   public void run() {
   Session session=sf.openSession();
   session.beginTransaction();
   for(int i=0;i<5;i++){
   Long id= new Long(random.nextInt(10)+1);
   System.out.println(Thread.currentThread().getName()+" "+id);
   User u=(User)session.get(User.class,id);
   u.setName(Math.random()+"");
   }
   session.getTransaction().commit();
   session.close();
   }
   },"thread"+i);
   t.start();
   }
   Thread.sleep(10000);
   }

该测试开启10个线程,在每个线程中的同一个事务中,随机得到5个User对象,并修改名字,然后提交事务。运行测试,99%的情况下都会报错:

  Caused by: com.mysql.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:941)
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2941)
   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
   at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
   at com.mysql.jdbc.Connection.execSQL(Connection.java:3249)
   at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1268)
   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1541)
   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1455)
   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1440)
   at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
... 16 more

造成了死锁,异常产生原因简单分析如下:

假设Thread1得到的User对象的顺序为1,4,6,9,3;Thread2得到的User对象的顺序为2,3,9,8,4;那么假设当Thread1运行到update4的时候,锁住ID:4这行数据,Thread2运行到update9,锁住ID:9这行数据,Thread1运行到update 9的时候等待Thread2释放ID:9这行数据的锁,Thread2运行到update 4的时候,等待Thread1释放ID:4这行数据的锁,造成死锁。

如果修改hibernate配置文件:

  <property name="hibernate.order_updates">true</property>

再次运行,运行测试成功。

在update的时候,ID排序了。执行过程简单分析如下:

Thread1得到User对象的顺序为1,4,6,9,3;但是在更新的时候顺序调整为1,3,4,6,9;

Thread2得到User对象的顺序为2,3,9,8,4;但是在更新的时候顺序调整为2,3,4,9,8;

那么当Thread2更新ID:3的时候,就会等着Thread1释放锁,而不会锁住任何ID:3之前的数据,所以不会造成Thread1的死锁,所以能正常运行。(MySQL总是一条一条执行SQL)。

个人认为这个选项建议设置为true。

Hibernate 配置详解(7)的更多相关文章

  1. Hibernate 配置详解(9)

    hibernate.cache.use_structured_entries Hibernate文档上介绍,该属性是用于把对象以一种更易读的方式放到二级缓存中,这样,在对二级缓存进行监控的时候就更容易 ...

  2. Hibernate 配置详解(2)

    6) hibernate.session_factory_name: 配置一个JNDI名称,通过Configuration对象创建的SessionFactory会绑定到JNDI下该名称中.一般名字格式 ...

  3. Hibernate 配置详解(5)

    9) hibernate.batch_fetch_style: 该配置是hibernate4.2.0新添加的,使用这个设置可以配置hibernate在做batch-fetch的时候,生成SQL的策略. ...

  4. Hibernate 配置详解(8)

    hibernate.generate_statistics 这个配置大家应该都很熟悉,用于开启Hibernate统计信息,便于对Hibernate相关性能调试提供数据依据.在开发过程当中,可以把这个选 ...

  5. Hibernate 配置详解(12) 补充

    hibernate.hbm2ddl.import_files_sql_extractor 这个配置项用于补充这篇文章: http://blog.csdn.net/stefwu/article/deta ...

  6. Hibernate 配置详解(12) 其实我也不想用这么土的名字

    hibernate.hbm2ddl.import_files 这个配置用于在hibernate根据映射文件执行DDL之前,如果我们自己设置了要事先运行的SQL文件,hibernate就会先执行这些SQ ...

  7. Hibernate 配置详解(11)

    hibernate.session_factory_name_is_jndi 配置hibernate.cfg.xml中SessionFactory的name属性是否作为JNDI名称绑定.默认是true ...

  8. hibernate二级缓存ehcache hibernate配置详解

    <!-----------------hibernate二级缓存ehcache------------------------->hibernate配置 <prop key=&quo ...

  9. Hibernate配置详解

    <!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> <?xml version='1.0' ...

随机推荐

  1. 【milonga】什么意思_英语milonga在线翻译_有道词典

    [milonga]什么意思_英语milonga在线翻译_有道词典 milonga 网络释义英英释义   米隆加 本届探戈艺术节表演最受观众欢迎的是热情欢快的米隆加(Milonga)舞曲探戈,为了吸引年 ...

  2. oracle数据库中insert与select

    前几天遇到了一个问题,insert语句中,不仅要insert页面传过来的值,还要insert select的值. 语句应该这样写: insert into 表1(字段a,字段b,...) select ...

  3. JSP简单练习-使用JDOM创建xml文件

    注意:在编写代码前,请确保该Web文件夹下的"WEB-INF/lib"下包括jdom.jar包! <%@ page language="java" con ...

  4. poj-3895-Cycles of Lanes 简单DFS

    题目链接: http://poj.org/problem?id=3895 题目意思: 在无向连通图中图中找一个经过边数最多的环. 解题思路: 从任意一点直接DFS,不用回溯,注意构成环的话至少有3条边 ...

  5. [课堂实践与项目]NavigationController与TabBarController的综合使用及易错点分析(包含消息提醒,app更新)

    陈述:我们在使用tabbarController的时候,我们总会和NavagationController联合起来.但是不联合的时候又是什么样的一种pool的情况呢?我们就单单的 TabBarCont ...

  6. 浮点数在计算机内存中的表示(IEEE 754规定1位是符号位,8位是指数,剩下的23位为有效数字)

    本文转载自:阮一峰的博客,http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html 张玉彬的博客 h ...

  7. 棋盘问题 简单搜索DFS

    Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子 ...

  8. Swift - 使用xib添加新界面

    除了使用storyboard外,我们还可以使用xib来设计并创建页面. 1,下面通过一个样例来演示: (1)点击主界面的“信息”按钮,页面切换到信息界面 (2)点击信息界面的“返回”,关闭信息界面,回 ...

  9. 我们熟悉的Textbox

    创建只读文本框 方法一: 可用Readonly属性防止用户编辑文本框内容.将Readonly属性设置为True后,用户就可以滚动文本框中的文本并将其突出显示,但不能作任何更改.将Readonly属性设 ...

  10. 用Stack实现对多线程的管理范例

    多线程就是并发技术,当线程数量超过一定数量时,系统响应就会变慢,所以就必须对线程数量进行控制,那么采用哪种控制方法呢?采用Stack类模仿堆栈,之所以说是模仿,就是因为Stack类毕竟不是真实的堆栈, ...