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. Java_1Lesson

    cmd使用 进入硬盘分区:D: E: F: 查看目录 dir 进入文件夹 “cd 文件名” .使用javac编译器编译运行. Javac 文件名 运行java程序 Java 文件名 第一个程序 pub ...

  2. HDU 1251 统计难题 (字符串-Trie树)

    统计难题 Problem Description Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单 ...

  3. iPhone5C三大看点:性能不输iPhone5 或售3399元

    乐杨俊编辑修改转载: iPhone 5C的发售时间或最早在9月18日,抢在中秋节前:最迟至国庆十一假期期间. [IT商业新闻网综合讯](记者 林涛)苹果2013年秋季发布会还有几个小时即将开幕,除了i ...

  4. iOS依据字符串计算UITextView高度

    iOS计算字符串高度,有须要的朋友能够參考下. 方法一:ios7.0之前适用 /** @method 获取指定宽度width,字体大小fontSize,字符串value的高度 @param value ...

  5. poj 3466 A Simple Problem with Integers

    题目链接:http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 思路 ...

  6. EasyUI - Panel 面板控件

    效果: html代码: <div id="p" style="padding: 10px;"> <p>panel content.< ...

  7. 基于visual Studio2013解决面试题之0603调整数组

     题目

  8. Mac Eclipse+Maven+TestNg+ReportNg 生成测试报告

    TestNG 是java 的单元测试框架,功能很强大,很方便,但是自动生成的测试报告有待改善,可以使用TestNg 自带的TestNG_xslt更改TestNG报告的样式,这里主要讲解ReportNg ...

  9. tomcat7 启动报错(转)

    不加载任何自己的项目启动即报错:   严重: Error deploying web application directory D:\tomcat7.0.30\webapps\docs java.l ...

  10. 基于visual Studio2013解决面试题之0303数组求和

     题目