缓存问题:
/** 使用 Query.executeUpdate() 缓存中数据不同步 解决办法
* Table -> T1oo(id,name)
* Table -> T2oo(id,avg,aid)
* 外键 T1oo.id->T2oo.aid
* Session.createQuery("delete T1oo") -> Query.executeUpdate()
*/
public void testExecuteUpdate(){
System.out.println( " \r\n\r\n********************ExecuteUpdate************************ " );
T1oo t1oo = new T1oo();
t1oo.setName( " liukaiyi " );
HibernateSessionFactory.closeSession();
Session session = HibernateSessionFactory.currentSession();
Transaction tr1 = session.beginTransaction();
// t1 成为 持久状态 一级缓存中 加载
session.saveOrUpdate(t1oo);
// 直接一条语句删除T1oo,缓存无法同步
// 一级缓存中还有 t1
Query qu = session.createQuery( " delete T1oo " );
try {
qu.executeUpdate();
} catch (Exception e) {
System.out.println( " //err: 有级联 单使用 delete T1oo 还要delete T2oo.aid = T1oo.id// " );
List list = session.createQuery( " from T1oo " ).list();
for (Iterator it = list.iterator();it.hasNext();){
Query t2qu = session.createQuery( " delete T2oo where aid=:id " );
t2qu.setInteger( " id " , ((T1oo)it.next()).getId().intValue());
t2qu.executeUpdate();
}
qu.executeUpdate();
}
tr1.commit();
Transaction tr2 = session.beginTransaction();
// 这直接通过一级缓存中加载t2,但DB中以没有此条数据
t1oo = (T1oo)session.load(T1oo. class ,t1oo.getId());
t1oo.setName( " google " );
try {
tr2.commit();
} catch (Exception e) {
System.out.println( " //err: update(t1oo)->DB 中数据库中没有 t1oo // " );
}
System.out.println( " 一级缓存清空前 " + session.get(T1oo. class ,t1oo.getId()) );
session.evict(t1oo);
System.out.println( " 一级缓存清空后 " + session.get(T1oo. class ,t1oo.getId()) );
// 不把t1oo id 为空,否则当在saveOrUpdate时候就会以为是游离态 update了
t1oo.setId( null );
// id=null insert 调用
session.saveOrUpdate(t1oo);
tr2.commit();
Transaction tr3 = session.beginTransaction();
session.delete(t1oo);
tr3.commit();
session.close();
HibernateSessionFactory.closeSession();
}
结果是:
********************ExecuteUpdate************************
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: delete from t1oo
//err: 有级联 单使用 delete T1oo 还要delete T2oo.aid = T1oo.id//
Hibernate: select t1oo0_.id as id, t1oo0_.name as name0_ from t1oo t1oo0_
Hibernate: delete from t2oo where aid=?
Hibernate: delete from t2oo where aid=?
Hibernate: delete from t2oo where aid=?
Hibernate: delete from t1oo
Hibernate: update t1oo set name=? where id=?
//err: update(t1oo)->DB 中数据库中没有 t1oo //
一级缓存清空前 hbn.bean.T1oo@287
Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=?
一级缓存清空后 null
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: delete from t1oo where id=?
Get Load 区别 :
/** Get Load 区别 (在commit前要 session.flush())
* Table -> T1oo(id,name)
* 1.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出异常
* 2.Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。
* 3.load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,
* 如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
*/
public void testGetLoad() throws Exception {
System.out.println("\r\n\r\n********************Get<>Load************************");
Session session = HibernateSessionFactory.currentSession();
// 数据准备
T1oo t1oo = new T1oo();
t1oo.setName("liu");
Transaction t1 = session.beginTransaction();
session.saveOrUpdate(t1oo);
// 为什么这会错?
//session.evict(t1oo);
//session.flush();
t1.commit();
session.evict(t1oo);
Transaction t2 = session.beginTransaction();
System.out.println("一级缓存是否有t1oo(load)->"+session.contains(t1oo));
//这时候t1oo为 CGlib生成的代理类
t1oo = (T1oo)session.load(T1oo.class,t1oo.getId());
System.out.println(" 延迟加载出现:select.. t1oo0_.id=? 表的其他属性加载 ");
t1oo.setName("load list");
//后在 update
t2.commit();
session.evict(t1oo);
Transaction t3 = session.beginTransaction();
System.out.println("一级缓存是否有t1oo(get)->"+session.contains(t1oo));
//这时候t1oo为 CGlib生成的代理类
t1oo = (T1oo)session.get(T1oo.class,t1oo.getId());
System.out.println(" 没有延迟加载出现");
t1oo.setName("get list");
//后在 update
t3.commit();
session.evict(t1oo);
Transaction tr3 = session.beginTransaction();
session.delete(t1oo);
tr3.commit();
session.close();
HibernateSessionFactory.closeSession();
}
结果
********************Get<>Load************************
Hibernate: insert into t1oo (name, id) values (?, ?)
一级缓存是否有t1oo(load)->false
延迟加载出现:select.. t1oo0_.id=? 表的其他属性加载
Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=?
Hibernate: update t1oo set name=? where id=?
一级缓存是否有t1oo(get)->false
Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=?
没有延迟加载出现
Hibernate: update t1oo set name=? where id=?
Hibernate: select t2ooset0_.aid as aid1_, t2ooset0_.id as id1_, t2ooset0_.id as id0_, t2ooset0_.avg as avg1_0_, t2ooset0_.aid as aid1_0_ from t2oo t2ooset0_ where t2ooset0_.aid=?
Hibernate: delete from t1oo where id=?
Set 集合的识别:
/** Set 集合的识别
* Table -> T1oo(id,name)
* Table -> T2oo(id,avg,aid)
* 外键 T1oo.id->T2oo.aid
* T1oo <set name="t2ooSet" inverse="false" cascade = "all" >
* T2oo <many-to-one name="t1oo" column="aid" class="T1oo" />
* cascade='insert' 是一定要的
* 当 T1oo没有 inverse="true" 主动权的时候,要双项关联
* t1oo.getT2ooSet().add(t2oo1);
* t1oo.getT2ooSet().add(t2oo2);
* t2oo1.setT1oo(t1oo);
* t2oo2.setT1oo(t1oo);
* 要不后sql为:
* Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
* Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
* +----+-----+------+
* | id | avg | aid |
* +----+-----+------+
* | 1 | 24 | NULL |
* | 2 | 23 | NULL |
* +----+-----+------+
* 当 T1oo有 inverse="false"主动权的时候
* t1oo.getT2ooSet().add(t2oo1);
* t1oo.getT2ooSet().add(t2oo2);
* Sql语句为:
* Hibernate: insert into t1oo (name, id) values (?, ?)
* Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
* Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
* Hibernate: update t2oo set aid=? where id=?
* Hibernate: update t2oo set aid=? where id=?
* | 3 | 24 | 12 |
* | 4 | 23 | 12 |
* +----+-----+------+
*/
public void testSet(){
System.out.println("\r\n\r\n********************Set************************");
T1oo t1oo = new T1oo();
t1oo.setName("list");
T2oo t2oo1 = new T2oo(); t2oo1.setAvg(new Integer(23));
T2oo t2oo2 = new T2oo(); t2oo2.setAvg(new Integer(24));
Session session = HibernateSessionFactory.currentSession();
Transaction tr1 = session.beginTransaction();
session.save(t1oo);
t1oo = (T1oo) session.load(T1oo.class,t1oo.getId());
t1oo.setT2ooSet(new HashSet()) ;
t1oo.getT2ooSet().add(t2oo1);
t1oo.getT2ooSet().add(t2oo2);
System.out.println( t1oo.getT2ooSet().size()+"" );
tr1.commit();
System.out.println();
T2oo t2oo3 = new T2oo(); t2oo3.setAvg(new Integer(25));
T1oo t1oo2 = new T1oo(); t1oo2.setName("mz");
t2oo3.setT1oo(t1oo2);
Transaction tr2 = session.beginTransaction();
session.save(t2oo3);
try {
tr2.commit();
} catch (Exception e) {
System.out.println("//err: 没有主动权 cascade = 'all' 不可以级联save t1oo //");
}
session.close();
HibernateSessionFactory.closeSession();
}
结果是:
********************Set************************
2
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
Hibernate: update t2oo set aid=? where id=?
Hibernate: update t2oo set aid=? where id=?
//err: 没有主动权 cascade = 'all' 不可以级联save t1oo //
inverse 使用
说明约定-如:
1.表属性 :T1oo->id,name
T2oo->id,avg,aid( 外键 ),version
2.代码过程是:Save->t1oo对象(T1oo 外键 T2oo)
T1oo t1oo = new T1oo();
t1oo.setName("xx");
t1oo.setT2ooSet(new HashSet());
T2oo t2oo2 = new T2oo(24);
//t2oo2.setT1oo(t1oo); (在下面的本用例表中的第3属性 )
t1oo.getT2ooSet().add(t2oo2); (在下面的本用例表中的第2属性 )
session.save(t1oo);
3.本例表使用:
T1oo.hbm.xml ->
<set name="t2ooSet" inverse="true" cascade = "all" > (在下面的本用例表中的第1,2属性 )
<key column="aid"/>
<one-to-many class="T2oo"/>
</set>
T2oo.hbm.xml ->
<many-to-one name="t1oo" column="aid" class="T1oo" cascade="all" /> (在下面的本用例表中的第1,2属性 )
结合上面说明得表为:
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | all | | |
+-------+-------+-------+ true | false |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
4.执行 Hibernate语句 :
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
5.结果为:
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 2 | 24 | NULL | 0 | //主要就是看 aid属性
+----+-----+------+---------+
1 row in set (0.00 sec)
mysql> select * from t1oo; // 因为 T1oo总是可以 Save 下面就不再提了
+----+------+
| id | name |
+----+------+
| 2 | xx |
+----+------+
1 row in set (0.00 sec)
可改项:
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | 可改4 | 可改2 | | |
+-------+-------+-------+ | 可改1 |
| t2oo | | 可改3 | | |
+-------+-------+-------+----------+----------+
主本:
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | all | | |
+-------+-------+-------+ true | true |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | 1 | 0 |
+----+-----+------+---------+
1 row in set (0.00 sec)
改1
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | all | | |
+-------+-------+-------+ true | false |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | NULL| 0 |
+----+-----+------+---------+
1 row in set (0.00 sec)
改2
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | | | |
+-------+-------+-------+ true | true |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Empty set (0.00 sec)
改2 改1
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | | | |
+-------+-------+-------+ true | false |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Empty set (0.00 sec)
改3
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | all | | |
+-------+-------+-------+ true | true |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | 1 | 0 |
+----+-----+------+---------+
1 row in set (0.00 sec)
改3 改2
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | | | |
+-------+-------+-------+ true | true |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Empty set (0.00 sec)
改3 改1
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | all | | |
+-------+-------+-------+ true | false |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | NULL | 0 |
+----+-----+------+---------+
1 row in set (0.00 sec)
改3 改2 改1
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | true | | | |
+-------+-------+-------+ true | false |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Empty set (0.00 sec)
改4
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | all | | |
+-------+-------+-------+ true | true |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
Hibernate: update t2oo set aid=? where id=?
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | 1 | 0 |
+----+-----+------+---------+
1 row in set (0.02 sec)
改4 改1
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | all | | |
+-------+-------+-------+ true | false |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
Hibernate: update t2oo set aid=? where id=?
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | 1 | 0 |
+----+-----+------+---------+
1 row in set (0.00 sec)
改4 改2
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | | | |
+-------+-------+-------+ true | true |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: update t2oo set aid=? where id=?
Empty set (0.00 sec)
改4 改3
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | all | | |
+-------+-------+-------+ true | true |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
Hibernate: update t2oo set aid=? where id=?
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | 1 | 0 |
+----+-----+------+---------+
1 row in set (0.00 sec)
改4 改3 改2
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | | | |
+-------+-------+-------+ true | true |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: update t2oo set aid=? where id=?
Empty set (0.00 sec)
改4 改1 改2
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | | | |
+-------+-------+-------+ true | false |
| t2oo | | all | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: update t2oo set aid=? where id=?
Empty set (0.00 sec)
改4 改1 改3
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | all | | |
+-------+-------+-------+ true | false |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?)
Hibernate: update t2oo set aid=? where id=?
mysql> select * from t2oo;
+----+-----+------+---------+
| id | avg | aid | version |
+----+-----+------+---------+
| 1 | 24 | 1 | 0 |
+----+-----+------+---------+
1 row in set (0.02 sec)
改4 改3 改2 改1
+-------+-------+-------+----------+----------+
|hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo|
+-------+-------+-------+----------+----------+
| t1oo | false | | | |
+-------+-------+-------+ true | false |
| t2oo | | | | |
+-------+-------+-------+----------+----------+
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: update t2oo set aid=? where id=?
Empty set (0.00 sec)
环境:
private SessionFactory sessionFactory;
protected void setUp() throws Exception {
super .setUp();
// 利用java反射得到 HibernateSessionFactory ->
// private static org.hibernate.SessionFactory sessionFactory;
// 要模拟 并发 要 HibernateSessionFactory 得出的 有 threadLocal 不行
// 要
HibernateSessionFactory.currentSession();
HibernateSessionFactory.closeSession();
Field field = HibernateSessionFactory. class .getDeclaredField( " sessionFactory " );
field.setAccessible( true );
sessionFactory = (SessionFactory) field.get(HibernateSessionFactory. class );
}
protected void tearDown() throws Exception {
super .tearDown();
}
悲观锁:
/** 悲观锁问题 线程模拟 并发
* Table -> T1oo(id,name)
* +----+------+
* | id | name |
* +----+------+
* | 4 | xx1 |
* +----+------+
*/
public void ctestLock() throws Exception {
// insert test Data 测试数据
Session seInsert = sessionFactory.openSession();
Transaction tr = seInsert.beginTransaction();
T1oo testUse = testUse = new T1oo();
testUse.setName( " liukaiyi_test " );
seInsert.save(testUse);
tr.commit();
System.out.println( " **************Test Use Bean : insert******************* " );
seInsert.close();
Integer testId = testUse.getId();
//并发模拟
Session session1 = sessionFactory.openSession();
Session session2 = sessionFactory.openSession();
final Transaction tr1 = session1.beginTransaction();
Transaction tr2 = session2.beginTransaction();
Query qu1 = session1.createQuery( " from T1oo t1oo where t1oo.name='liukaiyi_test' " );
Query qu2 = session2.createQuery( " from T1oo t1oo where t1oo.name='liukaiyi_test' " );
//加悲观锁
qu1.setLockMode( " t1oo " ,LockMode.UPGRADE);
final Object bean1 = qu1.uniqueResult();
Object bean2 = qu2.uniqueResult();
T1oo t1oo2 = (T1oo)bean2;
t1oo2.setName( " run1 " );
new Thread(
new Runnable(){
public void run() {
try {
System.out.println( " ********解锁准备********* " );
Thread.sleep( 10 * 1000 );
T1oo t1oo1 = (T1oo)bean1;
t1oo1.setName( " run2 " );
tr1.commit();
System.out.println( " ********解锁成功t********* " );
} catch (InterruptedException e) {e.printStackTrace();}
}
}
).start();
/ /这里会 等待十秒后 tr1解锁 /
tr2.commit();
session1.close();
session2.close();
// delete Test Date 删除测试数据
Session seDelete = sessionFactory.openSession();
Transaction trD = seDelete.beginTransaction();
Object obj = seDelete.createQuery( " from T1oo t where t.id=:id " ).
setInteger( " id " ,testId.intValue()).
uniqueResult();
seDelete.delete(obj);
trD.commit();
System.out.println( " **************Test Use Bean : delete************** " );
seDelete.close();
}
乐观锁:
/** 乐观锁问题
* Table -> T1oo(id,name)
* T2oo.hbn.xml <class> +> optimistic-lock="version"
* id下面 +> <version name="version" type="integer" column="version" />
* +---------+---------+------+
* | Field | Type | Null |
* +---------+---------+------+
* | id | int(11) | |
* | avg | int(11) | |
* | aid | int(11) | YES |
* | version | int(11) | YES |
* +---------+---------+------+
* 注意:要在数据库中多加一列
* mysql> alter table T2OO add version int;
*/
public void testOpLock() throws Exception{
//添加测试数据
Session session = sessionFactory.openSession();
Transaction trI = session.beginTransaction();
Connection conn = session.connection();
T2oo t2oo = new T2oo();
T1oo t1oo = new T1oo( " t1ooOpLock " );
t1oo.setT2ooSet( new HashSet());
t2oo.setAvg( new Integer( 23 ));
t2oo.setT1oo(t1oo);
t1oo.getT2ooSet().add(t2oo);
session.save(t2oo);
trI.commit();
session.clear();
session.close();
//并发模拟
Session se1 = sessionFactory.openSession();
Session se2 = sessionFactory.openSession();
Transaction tr1 = se1.beginTransaction();
Transaction tr2 = se2.beginTransaction();
T1oo obj1 = (T1oo)se1.load(T1oo. class , new Integer( 1 ));
T1oo obj2 = (T1oo)se2.load(T1oo. class , new Integer( 1 ));
((T2oo)obj1.getT2ooSet().iterator().next()).setAvg( new Integer( 9 ));
((T2oo)obj2.getT2ooSet().iterator().next()).setAvg( new Integer( 10 ));
tr1.commit();
try {
tr2.commit();
} catch (Exception e) {
se2.clear();
tr2.commit();
// tr2报错
} finally {
se1.close();
se2.close();
}
//测试数据删除
Session dele = sessionFactory.openSession();
Transaction tr = dele.beginTransaction();
dele.delete(obj1);
tr.commit();
dele.close();
HibernateSessionFactory.closeSession();
}
|