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. 在SharePoint 2013 中使用文档库Scheduling (计划公布功能)

    本文讲述在SharePoint2013 中使用文档库Scheduling (计划公布功能)的步骤和注意的事项. 文档库Scheduling (计划公布功能) 用于设定当文档通过审批后特定的时间区间内才 ...

  2. EasyUI - DataGrid 组建 - [ 搜索功能 ]

    效果: html代码: 使用css加载的方式,所以要在写html代码,也可以使用js操作. <div> <!--使用JS加载方式--> <table id="t ...

  3. Endnote X6 如何修改输出格式(output style)成为自己想要的输出格式:

    Endnote X6 如何修改输出格式(output style)成为自己想要的输出格式: (1)首先尝试在endnote output style 网站中查找: http://www.endnote ...

  4. OCP-1Z0-042-V12.39-47题

    47.Which two database operations can be performed at the mount stage of database startup? 题目解析: A和E在 ...

  5. tq2440+fedora安装qt4.5

    1. make[1]: arm-none-linux-gnueabi-g++:命令未找到 make[1]: *** [.obj/release-shared-emb-arm/qatomic_arm.o ...

  6. jQuery中对 input 控件的操作

    jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关 1.获取值 jquery取radio单选按钮的值 $(" ...

  7. 全方位深度剖析--性能测试之LoardRunner 介绍

    一.介绍 LoardRunner是一种预测系统行为和性能负载的测试工具.通过模拟上千万用户实施并发负载及实时性能监控的方式来确认和查找系统的瓶颈,LoardRunner能够对整个企业架构进行测试.通过 ...

  8. PO经批准的订单API

    DECLARE l_return_status VARCHAR2(1); l_exception_msg VARCHAR2(4000); BEGIN mo_global.set_policy_cont ...

  9. c#后台弹出提示

    Page.ClientScript.RegisterClientScriptBlock(typeof(string), "", @"<script>alert ...

  10. SVM(三)—Kernels(核函数)

    (整理自AndrewNG的课件,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 内容整理中...