【问题标题】:Spring programmatic transaction with parameter带参数的 Spring 程序化事务
【发布时间】:2010-01-21 19:46:07
【问题描述】:

我正在使用 Spring 处理一些数据访问逻辑,我的问题与事务有关。事务文档http://static.springsource.org/spring/docs/2.5.x/reference/transaction.html 表明您可以实现声明式或编程式事务。我选择使用程序化方法,以便更好地控制所交易的内容。

基本模式如下所示:

Product product = new Product();
// load properties 

// how do I pass my product object instance to my anonymous method?   
transactionTemplate.execute(
      new TransactionCallbackWithoutResult() 
      {
       protected void doInTransactionWithoutResult (TransactionStatus status)
       {
        // transaction update logic here
        return;
       }}); 

也许我做错了,但是,我的问题是如何将参数传递给内部匿名方法?我想这样做的原因是我可以建立自己的开始事务之前的对象图(因为事务应该尽可能缩短时间,对吧?)我只希望在事务中运行一小部分逻辑(更新逻辑)。

[编辑]

到目前为止,我唯一的选择似乎是使用常量变量,或者只是将所有逻辑放在匿名委托中。这似乎是一个很常见的问题……您是如何在自己的代码中处理此类情况的?

【问题讨论】:

    标签: java hibernate spring transactions


    【解决方案1】:

    声明它final。匿名内部类可以访问final 局部变量:

    public void someMethod() {
        ...
        final Product product = new Product();
        ...
        transactionTemplate.execute( 
            new TransactionCallbackWithoutResult()  
            { 
                protected void doInTransactionWithoutResult (TransactionStatus status) 
                { 
                    doSomething(product);
                    return; 
                }}); 
        ...
    }
    

    【讨论】:

    • 我不能,product 是一个实例类型,它需要在包含方法中加载,我也不想让它成为类成员变量。包含方法将被重复调用,所以我不认为将其设为静态会起作用,除非我遗漏了什么。
    • @James:我的意思是最终的局部变量
    • 这个方法将被不同的线程调用,它在一个 web 应用程序中使用。如果我将局部变量设为final,那将不是线程安全的吗?
    • 变量上的final 关键字标记该变量是一个常量。它不像 C++ 中的 static
    • 詹姆斯——这样想吧。 someMethod 在线程一中执行并定义产品产品并冻结。 someMethod 在线程二中执行并定义产品产品,但它有自己的产品 - 它没有覆盖线程一中的产品,因为线程一的产品仅存在于线程一的执行中。当线程 2 放弃,线程 1 恢复时,线程 1 的产品仍然存在 - 它是实例变量,在执行两个线程可以同时使用的方法时必须小心。
    【解决方案2】:

    对于这样的事情,我使用以下ObjectHolder

    public class ObjectHolder<T> {
        private T m_object;
    
        public ObjectHolder( T object ) {
            m_object = object;
        }
    
        public T getValue() {
            return m_object;
        }
    
        public void setValue( T object ) {
            m_object = object;
        }
    }
    

    然后就可以使用了

    final ObjectHolder<Product> productHolder = 
        new ObjectHolder<Product>( new Product() );
    

    ...在您的匿名课程中,您可以通过

    访问您的Product
    productHolder.getValue();
    

    ...或者用

    改变它的实例
    productHolder.setValue( new Product() );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-17
      相关资源
      最近更新 更多