Spring integration TransactionSynchronizationFactory与JmsTransactionManager组合不工作

Spring integration TransactionSynchronizationFactory与JmsTransactionManager组合不工作,spring-integration,Spring Integration,我有一个案例,我读取一个文件,将内容转换为字符串。然后将字符串拆分为多个有效负载,并将这些有效负载分别发送到队列。我想使用JmsTransactionManager,以便发送所有消息或根本不发送任何消息 发送成功后,我希望将文件移动到存档文件夹,否则将其移动到失败文件夹。我已经读到,我可以使用transactionSynchronizationFactory来完成这项工作。但与JmsTransactionManager结合使用时,文件不会移动。如果我使用伪TransactionManager,那

我有一个案例,我读取一个文件,将内容转换为字符串。然后将字符串拆分为多个有效负载,并将这些有效负载分别发送到队列。我想使用JmsTransactionManager,以便发送所有消息或根本不发送任何消息

发送成功后,我希望将文件移动到存档文件夹,否则将其移动到失败文件夹。我已经读到,我可以使用transactionSynchronizationFactory来完成这项工作。但与JmsTransactionManager结合使用时,文件不会移动。如果我使用伪TransactionManager,那么文件将被移动,但我失去了JmsTransaction

我制作了一个简化版本来重现这个问题。(本例中的文件内容是一个简单的逗号分隔的值列表。)

所以我的问题是:TransactionSynchronizationFactory是否只与伪TransactionManager一起工作,还是应该与JmsTransactionManager一起工作

解决方案

我需要在JMTransaction上设置transactionSynchronization。大概是这样的:

@Bean
public TransactionSynchronizationFactory transactionSynchronizationFactory() {
    ExpressionParser parser = new SpelExpressionParser();

    ExpressionEvaluatingTransactionSynchronizationProcessor syncProcessor
            = new ExpressionEvaluatingTransactionSynchronizationProcessor();
    syncProcessor.setBeanFactory(applicationContext.getAutowireCapableBeanFactory());
    syncProcessor.setAfterCommitExpression(parser.parseExpression(
            "payload.renameTo(new java.io.File('test/archive' " +
                    " + T(java.io.File).separator + 'ARCHIVE-' + payload.name))"));
    syncProcessor.setAfterRollbackExpression(parser.parseExpression(
            "payload.renameTo(new java.io.File('test/fail' " +
                    " + T(java.io.File).separator + 'FAILED-' + payload.name))"));
    return new DefaultTransactionSynchronizationFactory(syncProcessor);
}
public JmsTransactionManager transactionManager() {
    JmsTransactionManager jmsTransactionManager = new JmsTransactionManager(connectionFactory);
    jmsTransactionManager.setTransactionSynchronization(AbstractPlatformTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
    return jmsTransactionManager;
}

我想你的问题是:

/**
 * Create a new JmsTransactionManager for bean-style usage.
 * <p>Note: The ConnectionFactory has to be set before using the instance.
 * This constructor can be used to prepare a JmsTemplate via a BeanFactory,
 * typically setting the ConnectionFactory via setConnectionFactory.
 * <p>Turns off transaction synchronization by default, as this manager might
 * be used alongside a datastore-based Spring transaction manager like
 * DataSourceTransactionManager, which has stronger needs for synchronization.
 * Only one manager is allowed to drive synchronization at any point of time.
 * @see #setConnectionFactory
 * @see #setTransactionSynchronization
 */
public JmsTransactionManager() {
    setTransactionSynchronization(SYNCHRONIZATION_NEVER);
}
/**
*为bean样式的使用创建一个新的JmsTransactionManager。
*注意:在使用实例之前必须设置ConnectionFactory。
*此构造函数可用于通过BeanFactory准备JmsTemplate,
*通常通过setConnectionFactory设置ConnectionFactory。
*默认情况下关闭事务同步,就像此管理器可能关闭的那样
*可以与基于数据存储的Spring事务管理器一起使用,如
*DataSourceTransactionManager,它对同步有更强的需求。
*在任何时间点,只允许一个管理器驱动同步。
*@see#设置连接工厂
*@see#设置事务同步
*/
公共jmtransactionmanager(){
setTransactionSynchronization(同步\u从不);
}

因此,您必须手动将其切换到
setTransactionSynchronization(AbstractPlatformTransactionManager.SYNCHRONIZATION\u ALWAYS)

好吧,我想你的问题是:

/**
 * Create a new JmsTransactionManager for bean-style usage.
 * <p>Note: The ConnectionFactory has to be set before using the instance.
 * This constructor can be used to prepare a JmsTemplate via a BeanFactory,
 * typically setting the ConnectionFactory via setConnectionFactory.
 * <p>Turns off transaction synchronization by default, as this manager might
 * be used alongside a datastore-based Spring transaction manager like
 * DataSourceTransactionManager, which has stronger needs for synchronization.
 * Only one manager is allowed to drive synchronization at any point of time.
 * @see #setConnectionFactory
 * @see #setTransactionSynchronization
 */
public JmsTransactionManager() {
    setTransactionSynchronization(SYNCHRONIZATION_NEVER);
}
/**
*为bean样式的使用创建一个新的JmsTransactionManager。
*注意:在使用实例之前必须设置ConnectionFactory。
*此构造函数可用于通过BeanFactory准备JmsTemplate,
*通常通过setConnectionFactory设置ConnectionFactory。
*默认情况下关闭事务同步,就像此管理器可能关闭的那样
*可以与基于数据存储的Spring事务管理器一起使用,如
*DataSourceTransactionManager,它对同步有更强的需求。
*在任何时间点,只允许一个管理器驱动同步。
*@see#设置连接工厂
*@see#设置事务同步
*/
公共jmtransactionmanager(){
setTransactionSynchronization(同步\u从不);
}

因此,您必须手动将其切换到
setTransactionSynchronization(AbstractPlatformTransactionManager.SYNCHRONIZATION\u ALWAYS)

尝试将
jmstrasactionmanager
作为
@Bean
。未从该
.transactional()
选项向ApplicationContext注册它。这不是问题所在。我在我原来的帖子中添加了解决方案。尝试将
JmsTransactionManager
作为
@Bean
。未从该
.transactional()
选项向ApplicationContext注册它。这不是问题所在。我在我原来的帖子中添加了这个解决方案。是的,现在它可以工作了!我不知道默认情况下同步是关闭的。谢谢你的帮助!我也是。JavaDocs是我们的朋友:)是的,现在它工作了!我不知道默认情况下同步是关闭的。谢谢你的帮助!我也是。JavaDocs是我们的朋友:)