2016-07-07 124 views
0

我們使用Spring Batch編寫我們的作業,並且它工作得很好。但是最近我們看到了一個截斷問題,這導致了一些關於spring batch如何存儲關於作業的元數據的問題。Spring批處理作業元數據持久性問題

  1. 每次作業運行時,sp​​ring批處理都會將有關作業的元數據存儲在數據庫中。有兩個表:batch_step_execution_context和batch_job_execution_context,它們將元數據保存在short_context和serialized_context兩列中。這兩列都保存了確切的數據,但short_context的限制爲2500個字符,因此數據被截斷。

爲什麼我們2列存儲的準確數據,如果我們擺脫short_context什麼影響可能它的工作

  • 現在我們使用的內存HSQL數據庫爲我們的工作。我們的工作之一拋出以下異常:

    org.springframework.dao.DataIntegrityViolationException:PreparedStatementCallback; SQL [UPDATE BATCH_JOB_EXECUTION_CONTEXT SET SHORT_CONTEXT =?,SERIALIZED_CONTEXT =? WHERE JOB_EXECUTION_ID =?];數據異常:字符串數據,右截斷;嵌套的例外是java.sql.SQLDataException:數據異常:字符串數據,右截斷

  • 更多堆棧跟蹤:

    Caused by: org.hsqldb.HsqlException: data exception: string data, right truncation 
        at org.hsqldb.error.Error.error(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.error.Error.error(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.types.CharacterType.castOrConvertToType(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.types.CharacterType.convertToType(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.StatementDML.getUpdatedData(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.StatementDML.executeUpdateStatement(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.StatementDML.getResult(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.StatementDMQL.execute(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.Session.executeCompiledStatement(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
        at org.hsqldb.Session.execute(Unknown Source) ~[hsqldb-2.3.3.jar!/:2.3.3] 
    

    這是特定於HSQL DB,因爲它工作正常進行的其他工作,即,它被適當地截斷它

    感謝

    +0

    serialized_context不是2500可變長度字符字段,short_context是serialized_context是文本字段 –

    回答

    0

    serialized_context列應爲CLOB(或HSQLDB LONGVARCHAR),不是2500個變長字符字段。檢查DDL here。如果您更改HSQLDB數據庫中的數據類型,則不應看到任何截斷。除此之外,我會告誡你不要在執行上下文中序列化太多,因爲它會嚴重影響性能。你存儲的是什麼,這麼大?

    +0

    它實際上是將batch元數據保存在db中的批處理。所以當你在每一步執行完成後將對象形成一步到另一步時,對象os的狀態就會保留在數據庫中。在作業結束時,執行上下文表將具有作業期間傳遞的所有對象的整個狀態。也正如我所說serialized_context是文本和short_context是字符變化(2500)字段。但我不知道爲什麼我們需要這兩個字段,因爲它們保存了相同的數據 –

    +0

    'serialized_context'列應該不是** 2500個字符。它是CLOB/Text/Longvarchar對象,僅在序列化數據大於2500個字符時用作溢出。不過,爲什麼你要通過上下文傳遞如此多的對象(或幾個非常大的對象)呢?在我們辦公室使用的超過100個批處理作業中,我們從未需要利用較大的'serialized_context'列。實際上,這樣做需要在創建作業存儲庫bean時註冊LOB處理程序。 –

    +0

    我們正在使用Tasklet作爲工作中的一個步驟,所以說當我們從數據庫讀取這一步時,然後寫入其他數據源是另一個數據源。因此,在這種情況下,我們將從db步驟讀取的對象傳遞給另一個步驟,並且這些對象可能具有可變大小。 –