根据Hibernate文档,在Hibernate抛出异常后使用会话是不安全的。
如果会话抛出异常,包括任何SQLException,立即回滚数据库事务,调用Session.close()并放弃会话实例。某些会话方法不会使会话处于一致状态。Hibernate抛出的任何异常都不能被视为可恢复的。确保通过在finally块中调用close()来关闭会话。
在我的代码中,我正在做批量插入。我正在使用会话工厂获取
会话。我的代码是这样的。
try {
//some code here....
....
Table1Entity table1Entity = .......
List<Table2Entity> table2Entities = .......
Session currentSession = sessionFactory.getCurrentSession();
for (int i = 0; i < table2Entities; i++) {
.............
currentSession.save(table2Entities.get(i));
if(i % batchSize == 0 || i + 1 == table2Entities) {
currentSession.flush();
currentSession.clear();
}
}
} catch (Exception e) {
currentSession.getTransaction().rollback();
//currentSession.close(); //According to documentation Session should be closed here
table1Entity.setError(true);
currentSession.save(table1Entity);//According to documentation Session should not be used here
.......
}
正如留档所说,抛出异常后不应使用会话。我的问题是,由于我使用的是当前会话
,我如何将table1Entity
保存在catch块中?我应该使用open会话()
方法或任何其他方式打开新会话吗?
我建议不要写入数据库,以防数据库连接出现异常。所以基本上,我认为你的方法有严重的问题,修复它很可能对你没有任何好处。
在这种情况下,您应该非常小心,无论发生什么情况,您的批处理都不会抛出异常。因此,如果确实发生了异常,您可以假设数据库是不可访问的,或者无论如何不会接受任何尝试。将错误写到其他地方(日志文件已经被证明是有用的)。
我可以看到你的方法似乎是可行的(比如我更新了所有有效的方法,我标记的其他方法。为了识别“其他”,我使用了一个例外),但它实际上从来都不是一个好主意,而是一种“机智”的情况别那么机智,这不会有回报的。
取而代之的是,以一种方式写下你的批次,让那些不会成为首选的批次返回一个正确的结果,上面写着“我没有工作”,并适当地处理它。
所以在你的情况下:
try {
//some code here....
....
Table1Entity table1Entity = .......
List<Table2Entity> table2Entities = .......
Session currentSession = sessionFactory.getCurrentSession();
for (int i = 0; i < table2Entities; i++) {
.............
// HERE you need to make sure that this call would succeed
currentSession.save(table2Entities.get(i));
if(i % batchSize == 0 || i + 1 == table2Entities) {
currentSession.flush();
currentSession.clear();
}
}
currentSession.save(table1Entity);
currentSession.getTransaction().commit();
} catch (Exception e) {
currentSession.getTransaction().rollback();
log.warn("Could not do what I wanted", e);
}
这要么计算完整,要么根本不计算,并为您提供一个包含消息的适当堆栈跟踪,所有消息都位于它所属的位置(日志)。
也许你想在打电话之前试探一下电话是否会成功。
如果你认为你必须做你想做的事情,请阅读CodeNewbie在他的答案下的评论:用< code > setGoingToWriteBatch(true)创建table1Entry,然后在批处理的末尾< code > setBatchWritten(true)。这样你就可以找到第一个是对的,而第二个不是。
这是一个try… catch块。你怎么能确定无论对table1Entity进行什么处理,都不会引发Hibernate异常?如果在处理table1Entity时确实出现了异常,那么试图将其保存在当前会话中可能会产生更大的问题。
我的建议是将表上的处理分成单独的尝试..捕捉块并在每个块中分别调用save。在引发异常后,试图在catch块内的同一会话中保存事务是不安全的,并且假设table1Entity中没有问题有时可能是违反直觉的。
我正在使用Spring In Action 3 Action学习Spring MVC,我已经实现了显示用户注册表的基本程序,一旦我们提交表单,它将使用进行验证。 这是我的Spring控制器: 这是我的Spitter类文件: 这是我的编辑。显示给用户注册的jsp文件: 要加载表单,我将访问URL为:,一旦表单被加载,我只需提交表单而无需输入任何详细信息,以便我可以检查我的表单是否得到验证。但是我得到
本文向大家介绍在MySQL中使用“ TYPE = InnoDB”会引发异常吗?,包括了在MySQL中使用“ TYPE = InnoDB”会引发异常吗?的使用技巧和注意事项,需要的朋友参考一下 您可以使用ENGINE = InnoDB代替TYPE = InnoDB,因为TYPE的用法在MySQL 5.1版中已过时。 我们用于示例的版本是MySQL 8.0.12。让我们检查MySQL版本。查询如下-
问题内容: 我有一个简单的方法,可将命令打印到屏幕上,扫描用户的输入,然后将其作为字符串返回。如果用户输入无效,它将通知用户并再次询问。该方法运行完美,但是我的讲师提到我们应该始终关闭资源,因此我回过头来添加了close方法,现在无论用户输入什么,每次调用该方法时都会收到NoSuchElementException。这是代码… 例外总是指向用户输入以scan.nextLine()。trim()开头
在java手册中,建议在使用lock()和unlock()时使用try-finally,但是当try块中从未引发异常时,这也是必要的?例如:
问题内容: 是否有可能在Java 引用上创建方法引用的原因 ?这样做可能永远是不正确的,但是会导致错误,以后很难找到: 问题答案: 是否有可能在Java 引用上创建方法引用的原因 ? 不是 ,但是Eclipse在这方面显然存在一个错误(编辑:此问题已得到修复)。根据规范,当您使用JDK的工具时,它会失败,并且在线上会出现NPE 。 证明:http://ideone.com/APWXna(或编译和本
你可以使用raise语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个Error或Exception类的直接或间接导出类。 如何引发异常 例13.2 如何引发异常 #!/usr/bin/python # Filename: raising.py classShortInputException(Exception): '''A u