簡體   English   中英

有什么辦法可以判斷是否在JTA中啟動了新事務

[英]Is there any way to tell if a new transaction is started in JTA

我將Wildfly用作Java EE服務器。 我們有一個框架可用於實現某種命令設計模式。

我將嘗試盡可能簡單地描述工作流程:

  • 每個命令都是一個實體,用於存儲有關命令的信息(執行時間戳,成功狀態等)。
  • 每個命令都有執行業務邏輯的CommandEJB
  • 我們所有的命令都是從Command類擴展的,而它們的EJB是從CommandEJB類擴展的
  • CommanEJB調用為特定命令覆蓋的run方法,在該方法中為該特定命令執行業務邏輯
  • 之后,CommandEJB嘗試保留Command對象(如第1點所述,該對象包含有關命令執行的信息)
  • 如果CommandEJB實現正在創建一個實體並將其持久化在run方法的實現中,那么我們總是在特定命令和該實體之間進行雙向關聯

我將嘗試編寫一些偽代碼來解釋其工作原理:

我有一個名為Person的實體,並且我有一個CreatePersonCmd,該命令應該創建一個新的人員並將其持久保存到數據庫中。 之后,框架將CreatePersonCmd持久保存到數據庫中。 執行命令時,Person實體和CreatePersonCmd實體通過以下方式鏈接

person.setCmd(cmd);

cmd.setPerson(person);

我有一個調用以下命令的SAOP Web服務:

@Stateless
@WebService
public class MyWebService {
CreatePersonCmd cmd = new CreatePersonCmd();
executor.execute(cmd);
}

我的CreatePersonCmd是CreatePersonCommand和Person之間的關系的所有者,因此如下所示:

public class CreatePersonCmd {
@JoinColumn
@OneToOne
private Person person;
}

關系的另一面是Person:

public class Person{
@OneToOne(mappedBy="person")
private CreatePersonCmd createPersonCmd;
}

在我的CreatePersonEJB(調用其運行方法實現)中:

public class CreatePersonCmdEJB extends CommandEJB {

public void run() {

    Person person = new Person("John Doe");
    createPersonCmd.setPerson(person);
    person.setCreatePersonCmd(createPersonCmd);
    em.persist(person);

}

之后,CommandEJB繼續執行並嘗試保存命令:

em.persist(createPersonCmd);

但是,執行永遠不會到達最后一行,並且在以下位置出現異常:

em.persist(person);

例外是:

Not-null property references a transient value - transient instance must be saved before current operation

奇怪的是,如果我使Person成為關系的所有者,則一切正常。

我做了一個簡單的示例,沒有我們的框架,該框架具有2個實體Customer和Address,它們也具有雙向的OneToOne關系,但是我進行了測試,無論我使用哪種持久化順序,它始終可以很好地執行。

這是偽代碼:

Customer c = new Customer("John Doe");
Address a = new Address("MyStreet", 1123);

c.setAddress(a);
a.setCustomer(c);

em.persist(c);
em.persist(a);

無論持久化順序是什么(地址或客戶至上,如果我同時擁有兩條線,它總是可以很好地實現)

但是,在我們的框架中,交易似乎在em.persist(person)之后結束,並且在我們的框架源代碼中沒有看到em.flush()。

有什么辦法可以知道我是否在同一筆交易中? 我嘗試通過em.getTransaction()獲取事務,但得到A JTA EntityManager cannot use getTransaction() ,可能是因為Java EE中的事務由應用程序容器管理。

如果已經插入createPersonCmd,則必須將其添加到當前工作集中。 那可以通過

createPersonCmd = em.merge(createPersonCmd)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM