2016-07-07 61 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步骤读取的对象传递给另一个步骤,并且这些对象可能具有可变大小。 –