Hibernate 配置详解(7)
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)的更多相关文章
- Hibernate 配置详解(9)
hibernate.cache.use_structured_entries Hibernate文档上介绍,该属性是用于把对象以一种更易读的方式放到二级缓存中,这样,在对二级缓存进行监控的时候就更容易 ...
- Hibernate 配置详解(2)
6) hibernate.session_factory_name: 配置一个JNDI名称,通过Configuration对象创建的SessionFactory会绑定到JNDI下该名称中.一般名字格式 ...
- Hibernate 配置详解(5)
9) hibernate.batch_fetch_style: 该配置是hibernate4.2.0新添加的,使用这个设置可以配置hibernate在做batch-fetch的时候,生成SQL的策略. ...
- Hibernate 配置详解(8)
hibernate.generate_statistics 这个配置大家应该都很熟悉,用于开启Hibernate统计信息,便于对Hibernate相关性能调试提供数据依据.在开发过程当中,可以把这个选 ...
- Hibernate 配置详解(12) 补充
hibernate.hbm2ddl.import_files_sql_extractor 这个配置项用于补充这篇文章: http://blog.csdn.net/stefwu/article/deta ...
- Hibernate 配置详解(12) 其实我也不想用这么土的名字
hibernate.hbm2ddl.import_files 这个配置用于在hibernate根据映射文件执行DDL之前,如果我们自己设置了要事先运行的SQL文件,hibernate就会先执行这些SQ ...
- Hibernate 配置详解(11)
hibernate.session_factory_name_is_jndi 配置hibernate.cfg.xml中SessionFactory的name属性是否作为JNDI名称绑定.默认是true ...
- hibernate二级缓存ehcache hibernate配置详解
<!-----------------hibernate二级缓存ehcache------------------------->hibernate配置 <prop key=&quo ...
- Hibernate配置详解
<!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> <?xml version='1.0' ...
随机推荐
- VC 为静态控件添加事件
操作系统:Windows 7软件环境:Visual C++ 2008 SP1本次目的:为静态控件添加事件,如:STATIC.Picture Control等等 有时候我们找到一个图片,为对话框背景添加 ...
- Objective-C中的SEL、IMP和Class类型
1.SEL类型 例子: SEL say; SEL skin; Objective-C 在编译的时候, 会根据方法的名字(包括参数序列),生成一个用 来区分这个方法的唯一的一个 ID,这个 ...
- Swift - 正则表达式的使用(附用户名、邮箱、URL等常用格式验证)
Swift虽然是一个新出的语言,但却不提供专门的处理正则的语法和类.所以我们只能使用古老的NSRegularExpression类进行正则匹配. 即先接受一个正则表达式的字符串,由此生成NSRegul ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(四)
零基础学Android开发:蓝牙聊天室APP第四讲 4.1 ListView控件的使用 4.2 BaseAdapter具体解释 4.3 ListView分布与滚动事件 4.4 ListView事件监听 ...
- ASP.NET - (Session)后台登陆时,判断是不是已经登陆,如果不是,跳转回登陆页
admin(小写):用户输入的账户. password(小写):用户输入的密码. 1.先将用户名和密码,存储到Session会话中. Session["Admin"] = admi ...
- io 测试
//其中能够实现编码的只有OutputStreamWriter和对应inputStreamReader package net; import java.io.BufferedWriter; impo ...
- 14.8.3 Identifying the File Format in Use 确认使用的文件格式;
14.8.3 Identifying the File Format in Use 确认使用的文件格式: 如果 你启用一个不同的文件格式使用 innodb_file_format configurat ...
- swift_将UIDatePicker到达的传播之间的时间差在数小时出现页面的事
今天,写swift demo当它来到了一个非常精彩的问题,我再次 present 使用页面出来 UIDatePicker 选择时间,然后再回到原来的主界面的时间,结果出现的问题:B页面的正常时间,传回 ...
- script:查看redo产生的历史信息
script:查看redo产生的历史信息 SQL> alter session set nls_date_format='dd-mon-yy'; SQL> set lines 160 p ...
- Hibernate(五)——经典解析一对一关联映射
前面两篇介绍了多对一.一对多的映射.今天分享下一对一的关联映射关系.有两种策略可以实现一对一的关联映射:主键关联.唯一外键关联. 主键关联——两个表有完全相同的主键值,来表示它们的一对一的关系.数据库 ...