Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 更新新事务范围内的对象_Java_Spring_Hibernate_Jpa - Fatal编程技术网

Java 更新新事务范围内的对象

Java 更新新事务范围内的对象,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我有一个与事务边界相关的问题,我无法找出哪里出了问题 @Transactional( propagation = Propagation.REQUIRED ) Class A { void methodA() { try { new B().callMethodB(obj) } catch(Exception e) { updateSomeProperty(obj1) } } @Transactional(propagation =

我有一个与事务边界相关的问题,我无法找出哪里出了问题

@Transactional( propagation = Propagation.REQUIRED )
Class A {
void methodA() {
     try {
     new B().callMethodB(obj)
     } catch(Exception e) {
           updateSomeProperty(obj1)
     }
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
void updateSomeProperty(Object obj1) {
     obj1.setProperty(1);
     obj1.save();       
}
        }

 Class B {

   public void callMethodB(Object obj) throws Exception {
    throws new Exception();  
 }

 }
问题是抛出错误时,我的对象没有更新。我还尝试从方法
updateSomeProperty
中触发SQL代码,但也不起作用

基本上我想更新对象的属性,不管是否抛出异常。

有什么想法吗?

您可以尝试指定norollboor=RuntimeException.class或您想要的任何其他类,希望它能让您更新数据库。i、 e.@Transactional(norollboor=RuntimeException.class)

,它不应该工作。因为您可以从类的另一个方法调用updateSomeProperty(obj1),并尝试更改默认事务行为(从REQUIRED更改为REQUIRED\u NEW)。但这是行不通的。这就是为什么发生异常时,所有更改都将回滚

默认情况下,Spring为接口创建代理,@Transactional注释应仅用于公共方法。这个方法应该从“外部”调用。如果您将从类中的另一个方法调用它们,@Transactional annotation将不起作用

您还可以更改xml中事务的默认设置(查看属性代理目标类和模式)。但我从未改变过这一点,也不记得它到底应该如何工作

<tx:annotation-driven transaction-manager="txManager" mode="..." proxy-target-class="..."/>
}

  • 实现此接口的某些测试类:

    @事务性(传播=propagation.REQUIRED,rollboor=Exception.class) @组成部分 公共类TestClass实现TestClassInterface{

    void testMethod();
    
    @Autowired
    private SpringDataFooDAO fooDao;
    
    public void testMethod() {
        try {
            Foo foo = fooDao.findOne(2L);
            System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
            System.out.println(TransactionSynchronizationManager.isActualTransactionActive());
            foo.setName("should be rolled back");
            new ExceptionThrower().doSomething("default string");
        } catch(Exception e) {
            updateSomeProperty(1L, "Changed name");
            throw new RuntimeException(e);
        }
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor=Exception.class)
    private void updateSomeProperty(long id, String newFooName) {
    
        System.out.println("   ---   ");
        System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
        System.out.println(TransactionSynchronizationManager.isActualTransactionActive());
    
         // Update property of test object.
         Foo foo = fooDao.findOne(id);
         foo.setName(newFooName);    
    }
    
    }

  • 具有引发异常的方法的另一个类:

    公共类例外Rower{

    public void doSomething(Object obj) throws Exception {
        throw new Exception();  
     }
    
    }

  • 注意,我从catch块重新抛出异常(我作为运行时异常执行此操作,因为我不需要在上层类中处理它)。这对于正确的外部事务回滚是必需的。

    请查看以了解如何使用@Transactional@事务性当使用spring代理时,需要应用很多**条件,在将其应用到代码中之前,您需要了解这些条件

    在代理模式(默认)下,只有外部方法调用 通过代理进入被拦截。这意味着 自调用,实际上是目标对象中调用 目标对象的另一种方法,不会导致实际的 即使调用的方法标记为 @事务性的

    考虑使用AspectJ模式(参见下表中的模式属性) 如果您希望将自调用与事务打包为 好。在这种情况下,首先不会有代理人; 相反,将编织目标类(即,其字节码将 要将@Transactional转换为上的运行时行为 任何一种方法


    上述安排非常适合开始一项新的交易,并进行与原始交易不同的其他工作

    在我的例子中出错的一件事是,在另一个事务中,我自己抛出了一个异常,导致第二个事务再次回滚

    So The thing is beware off exception in the transaction because they ensure that the database state rolls back. It is for what they are meant for.   
    

    谢谢

    创建一个自定义异常并使用它来抛出,还请在定义自定义异常时在as类级别注释上使用@ApplicationException(rollback=false)

    e、 g


    哪种方法void updateSomeProperty(对象obj1)或void methodA()?@gresdiplitude为您提供了到spring参考文档的良好链接。转到这里,阅读关于如何在spring中使用声明性事务的内容。之后,您将了解如何与他们合作。关于例子-在谷歌你可以找到很多例子。谢谢,我不耐烦了。我必须记住学习曲线:)对不起,如果我侮辱了你。我重读了我的评论,明白它似乎太引人注目了。我还添加了一个链接到非常好的文章。没有问题。感谢您的帮助查看spring参考链接,那里有很多示例,或者只是谷歌一下。你好,Nikhil。我上传了我的帖子,并为你发布了可能的解决方案。我测试了它,它在我的电脑上运行良好。因此,希望它能对您起作用。创建一个自定义异常并使用它来抛出,还请在定义自定义异常时在as类级别注释上使用@ApplicationException(rollback=false)。很高兴您发现了问题。我很惊讶没有人看到它。
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <compilerVersion>${compiler.version}</compilerVersion>
            <fork>true</fork>
            <source>1.7</source>
            <target>1.7</target>
        </configuration>
    </plugin>
    
    <compiler.version>1.7</compiler.version>
    <aspectj.version>1.6.12</aspectj.version>
    
    <org.springframework.version>3.1.0.RELEASE</org.springframework.version>
    <org.hibernate.version>4.1.0.Final</org.hibernate.version>
    <org.springdata.version>1.0.2.RELEASE</org.springdata.version>
    
    void testMethod();
    
    @Autowired
    private SpringDataFooDAO fooDao;
    
    public void testMethod() {
        try {
            Foo foo = fooDao.findOne(2L);
            System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
            System.out.println(TransactionSynchronizationManager.isActualTransactionActive());
            foo.setName("should be rolled back");
            new ExceptionThrower().doSomething("default string");
        } catch(Exception e) {
            updateSomeProperty(1L, "Changed name");
            throw new RuntimeException(e);
        }
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor=Exception.class)
    private void updateSomeProperty(long id, String newFooName) {
    
        System.out.println("   ---   ");
        System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
        System.out.println(TransactionSynchronizationManager.isActualTransactionActive());
    
         // Update property of test object.
         Foo foo = fooDao.findOne(id);
         foo.setName(newFooName);    
    }
    
    public void doSomething(Object obj) throws Exception {
        throw new Exception();  
     }
    
    So The thing is beware off exception in the transaction because they ensure that the database state rolls back. It is for what they are meant for.   
    
    @ApplicationException(rollback=false)
    public CustomException extends Exception{