Java 在单个hibernate会话中创建多个事务
我创建了一个Quartz作业,它在JBoss服务器的后台运行,负责定期更新一些统计数据(加上一些数据库标志) 要加载并持久化,我正在使用Hibernate4。除了一个故障外,一切正常 整个线程(即作业)被包装在一个事务中,随着时间的推移(随着数据量的增加),该事务会变得非常庞大,令人担忧。我试图将单个大事务分解为多个小事务,这样每个事务只处理一个子组数据 问题:我非常笨拙地试图将代码包装到循环中,并在循环的开始/结束处启动/结束事务。正如我所料,它没有起作用。我一直在各种论坛上寻找解决方案,但没有发现任何迹象表明在一个会话中管理多个事务(其中一次只有一个事务处于活动状态) 我对冬眠还比较陌生,如果能为我指明实现这一目标的方向,我将不胜感激 更新:添加代码演示我试图实现的目标,以及我所说的打破多个事务的意思。并在执行时进行堆栈跟踪Java 在单个hibernate会话中创建多个事务,java,hibernate,postgresql,transactions,Java,Hibernate,Postgresql,Transactions,我创建了一个Quartz作业,它在JBoss服务器的后台运行,负责定期更新一些统计数据(加上一些数据库标志) 要加载并持久化,我正在使用Hibernate4。除了一个故障外,一切正常 整个线程(即作业)被包装在一个事务中,随着时间的推移(随着数据量的增加),该事务会变得非常庞大,令人担忧。我试图将单个大事务分解为多个小事务,这样每个事务只处理一个子组数据 问题:我非常笨拙地试图将代码包装到循环中,并在循环的开始/结束处启动/结束事务。正如我所料,它没有起作用。我一直在各种论坛上寻找解决方案,但没
log.info("Starting Calculation Job.");
List<GroupModel> groups = Collections.emptyList();
DAOFactory hibDaoFactory = null;
try {
hibDaoFactory = DAOFactory.hibernate();
hibDaoFactory.beginTransaction();
OrganizationDao groupDao = hibDaoFactory.getGroupDao();
groups = groupDao.findAll();
hibDaoFactory.commitTransaction();
} catch (Exception ex) {
hibDaoFactory.rollbackTransaction();
log.error("Error in transaction", ex);
}
try {
hibDaoFactory = DAOFactory.hibernate();
StatsDao statsDao = hibDaoFactory.getStatsDao();
StatsScaledValuesDao statsScaledDao = hibDaoFactory.getStatsScaledValuesDao();
for (GroupModel grp : groups) {
try {
hibDaoFactory.beginTransaction();
log.info("Performing computation for Group " + grp.getName() + " ["
+ grp.getId() + "]");
List<Stats> statsDetail = statsDao.loadStatsGroup(grp.getId());
// Coputing Steps here
for (Entry origEntry : statsEntries) {
entry.setCalculatedItem1(origEntry.getCalculatedItem1());
entry.setCalculatedItem2(origEntry.getCalculatedItem2());
entry.setCalculatedItem3(origEntry.getCalculatedItem3());
StatsDetailsScaledValues scValues = entry.getScaledValues();
if (scValues == null) {
scValues = new StatsDetailsScaledValues();
scValues.setId(origEntry.getScrEntryId());
scValues.setValues(origEntry.getScaledValues());
} else {
scValues.setValues(origEntry.getScaledValues());
}
statsScaledDao.makePersistent(scValues);
}
hibDaoFactory.commitTransaction();
} catch (Exception ex) {
hibDaoFactory.rollbackTransaction();
log.error("Error in transaction", ex);
} finally {
}
}
} catch (Exception ex) {
log.error("Error", ex);
} finally {
}
log.info("Job Complete.");
根据我到目前为止所读到的关于Hibernate、会话和事务的内容,我的理解是。似乎在创建会话时,它会连接到线程,并在整个线程生命周期内或在调用commit或rollback时一直存在。因此,当提交第一个事务时,会话将被关闭,并且在线程的剩余生命周期内不可用
我的问题仍然是:我们如何在一个会话中进行多个事务处理?更多详细信息和一些示例将非常有用,但我认为我应该能够帮助您完成这里所写的内容 有一个静态SessionFactory(内存太大) 同样,对于您的事务,您也需要这样的东西
SomeClass object = new SomeClass();
Session session = sessionFactory().openSession() // create the session object
session.beginTransaction(); //begins the transaction
session.save(object); // saves the object But REMEMBER it isn't saved till session.commit()
session.getTransaction().commit(); // actually persisting the object
session.close(); //closes the transaction
这就是我如何使用我的交易,我不确定我是否一次做的交易和你们一样多。但与内存中的SessionFactory相比,session对象重量较轻
例如,如果希望一次保存更多对象,可以在一个事务中保存
SomeClass object1 = new SomeClass();
SomeClass object2 = new SomeClass();
SomeClass object2 = new SomeClass();
session.beginTransaction();
session.save(object1);
session.save(object2);
session.save(object3);
session.getTransaction().commit(); // when commit is called it will save all 3 objects
session.close();
希望这对你有所帮助,或者为你指明正确的方向。
我认为您可以配置您的程序来压缩事务
编辑
这是一个很棒的youtube教程。这家伙真的帮我搞定了
那么,如果第二个(第三个、第四个)“事务”失败,您该怎么办?您如何处理以前的数据?听起来像是一个黑客,可能会把你所有的数据都搞乱。您不应该根据性能定义事务,而应该根据业务规则的需要定义事务。开始看看为什么会出现“变慢”(反正我听起来很奇怪)以及:您使用的是哪种DBMS?博士后?甲骨文?@一匹没有名字的马,它不是一个黑客。数据本身由一个键分组,每个组可以有从几百条记录到一百万条记录的数据。以防特定事务失败。管理员知道,必须成功处理和保存rest和所有组。我正在使用Postgres。总之,成功完成的事务必须写入数据库,失败的事务必须回滚。这不会相互影响。我希望这能解释我的要求。谢谢。你的业务规则要么要求所有的东西都在一个交易中,然后打破它就是一个“黑客”。或者您的业务规则没有要求这样做,那么现有代码是错误的。将事务(您的业务规则要求)拆分为较小的事务是不正确的,尤其是当它仅用于性能时。“它不起作用”。呃。。。。细节?错误消息?确切的PostgreSQL版本?密码?
SomeClass object1 = new SomeClass();
SomeClass object2 = new SomeClass();
SomeClass object2 = new SomeClass();
session.beginTransaction();
session.save(object1);
session.save(object2);
session.save(object3);
session.getTransaction().commit(); // when commit is called it will save all 3 objects
session.close();