Java Spring Hibernate事务开销

Java Spring Hibernate事务开销,java,spring,hibernate,transactions,Java,Spring,Hibernate,Transactions,在将Hibernate3升级到Hibernate4之后,我被迫从基于spring的应用程序中删除HibernateTemplate。为了使Hibernate会话可用,我必须比以前更一致地使用事务标记。这要求我向服务层添加事务建议,并密切关注执行只读数据库操作的后台线程 我有两个数据源(我必须使用两个不同的数据库),第一个用于几乎每个应用程序请求,第二个仅用于特殊(比如1000个请求中的1个)请求。最简单的方法是使用方面在两个数据库的事务中包装这两种请求类型(我不必确定哪些请求需要哪个数据库),但

在将Hibernate3升级到Hibernate4之后,我被迫从基于spring的应用程序中删除HibernateTemplate。为了使Hibernate会话可用,我必须比以前更一致地使用事务标记。这要求我向服务层添加事务建议,并密切关注执行只读数据库操作的后台线程

我有两个数据源(我必须使用两个不同的数据库),第一个用于几乎每个应用程序请求,第二个仅用于特殊(比如1000个请求中的1个)请求。最简单的方法是使用方面在两个数据库的事务中包装这两种请求类型(我不必确定哪些请求需要哪个数据库),但我想知道这其中涉及的开销。实际的数据库连接获取和事务逻辑(如提交等)是否推迟到执行实际查询时?或者我的方法是否会导致启动和提交大量(实际上未使用的)事务

为了澄清,我有两个数据源,两个事务管理器,两个(相同的)“inServiceLayer”切入点的事务建议


谢谢你的帮助

关于“使用方面在事务中包装这两种请求类型”的确切含义是什么?您的问题表明您的应用程序没有正确分层。您应该有某种类型的数据访问层,其中事务逻辑要么以声明方式(
@transactional
)应用,要么以编程方式(
TransactionTemplate
)应用。这意味着没有命中数据库的请求永远不会打开事务

编辑:

如果不选择适当的分层,您肯定会招致事务处理的开销。Spring中用于事务划分的标准工具没有实现您想要的这种“延迟/按需”事务初始化。证明这一点的最简单方法是在您使用的事务管理器上启用调试/跟踪级别的日志记录。

我首先没有考虑开销,我在这里看到的最大问题是您的方法存在根本性缺陷。假设某些逻辑可以访问DB-1和DB-2,在DB-1中提交后,当您尝试提交DB-2时,出现了一些问题,需要回滚txn到DB-2,因为DB-1中的事务已经提交,所以DB-1和DB-2中的数据不一致

您的案例应该更好地利用分布式事务(我希望您的两个DB都支持XA),因此您在Spring point cut中只有1个(分布式)事务需要处理。而且,我相信(尽管我不确定)正常的XA事务不会盲目地在所有资源中创建底层事务(即,只有在需要时才创建底层txn)

因此,使用分布式txn可以为您提供更正确、具体、可维护和(可能)更少资源浪费的实现


进一步研究容器的相关设置。

谢谢您的回答。你是对的:应用程序不是理想的分层。有访问第一个数据库的类,访问第二个数据库的类,以及访问两个数据库的类。如果我有三个层来分隔这些类,我就可以正确地应用事务分隔。但就在今天,我无法轻松区分这些类,所以我选择在每种情况下都在两个数据库中打开一个事务。Adrian,非常感谢您的回复。幸运的是,DB-2大部分是只读的,DB-1已经获得了所有的生产数据。不过,分布式事务似乎是正确的想法。我不确定应该将哪个答案标记为正确答案-这两个答案都帮助了我,谢谢!:-)