简体   繁体   English

EJB Transactions属性:NOT_SUPPORTED和REQUIRES_NEW

[英]EJB Transactions attribute: NOT_SUPPORTED and REQUIRES_NEW

I am currently stuck in the following scenario: 我目前陷入以下情况:

I am trying to save object A into database. 我正在尝试将对象A保存到数据库中。 But A is made up by a lot of other objects, B, C, and B, C consists of objects D,E...there aa lot of nested objects, you know what I mean. 但是A由许多其他对象组成,B,C和B,C由对象D,E组成...有很多嵌套的对象,您知道我的意思。 Let call the whole process of saving A as transaction 1. 让我们将将A保存为事务1的整个过程称为1。

In the middle of transaction 1, when it comes to saving some object X(which is somewhat associated to A by a number of links), let's say it is the method saveX() that triggers saving X. In the saveX() method, the business logic requires to do another query for another object Y, let's say the method is queryY(). 在事务1的中间,当要保存某个对象X(通过许多链接在某种程度上与A相关联)时,可以说是saveX()方法触发了保存X。在saveX()方法中,业务逻辑需要对另一个对象Y进行另一个查询,假设方法是queryY()。

So when we call queryY(), and when it goes to the line of code that actually get all the results from the database, we have an exception. 因此,当我们调用queryY()并转到实际从数据库中获取所有结果的代码行时,就会出现异常。 Let's call this moment as T time. 我们将此时刻称为T时间。

The exception is 例外是

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: A.b -> B.

So what I think is, EJB container somewhat thinks at T time, when we need to do a query, it needs to commit the current transaction 1 and start transaction 2 to execute the query. 因此,我认为,EJB容器在T时间有点思考,当我们需要执行查询时,它需要提交当前事务1并启动事务2来执行查询。 And obviously the data related to A is not properly saved to the database yet, so the exception occurs. 显然,与A相关的数据尚未正确保存到数据库中,因此发生了异常。

So We need to somewhat suspend transaction 1 and resume it after we did the query instead of committing it at T time. 因此,我们需要稍微挂起事务1并在执行查询后恢复它,而不是在T时间提交它。 I did some research and I found @TransactionAttribute can solve the problem. 我做了一些研究,发现@TransactionAttribute可以解决问题。 The funny thing is that, I found out both solutions below works(no exception occurs and application is all right) if I put one of the two on the queryY() as an annotation: 有趣的是,如果我将两个解决方案之一放在queryY()上作为注解,那么我发现下面的两个解决方案都可行(没有异常,应用程序也可以)。

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 

I read the official doc related to the annoation: http://docs.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html 我阅读了与该注释有关的官方文档: http ://docs.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html

It makes sense that REQUIRES_NEW works. REQUIRES_NEW有效是有道理的。 But I don't understand why NOT_SUPPORTED works as well. 但是我不明白为什么NOT_SUPPORTED也能正常工作。 Obviously we need another transaction to call queryY() to finish the query. 显然,我们需要另一个事务来调用queryY()来完成查询。 And in the explanation of NOT_SUPPORTED, it does not mention it will start a new transaction after suspend the first transaction. 并且在NOT_SUPPORTED的说明中,没有提到它将在挂起第一个事务后开始新事务。

So my first question is, why NOT_SUPPORTED works? 所以我的第一个问题是,为什么NOT_SUPPORTED起作用? My second question is, why EJB container thinks the transaction 1 is ended and it needs to be committed at T time instead of regarding queryY as a part of transaction 1? 我的第二个问题是,为什么EJB容器认为事务1已结束并且需要在T时间提交,而不是将queryY视为事务1的一部分?

Thanks in advance! 提前致谢! Any help will be appreciated! 任何帮助将不胜感激!

This is not related to transaction propagation. 这与事务传播无关。 You should use one and only one transaction to save all your objects. 您应该只使用一个事务来保存所有对象。

This error that you get: 您得到的此错误:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: A.b -> B.

Is because you try to save A and there's no cascade between A and B. 是因为您尝试保存A,而A和B之间没有级联。

If A is the parent and B is the child (having a FK), then cascading the persist/merge operation from A to B makes sense. 如果A是父母,而B是孩子(具有FK),则将持久性/合并操作从A层叠到B是有意义的。 Otherwise, if B is a parent @OneToOne association, you need to save that first. 否则,如果B是父@OneToOne关联,则需要先保存该关联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM