Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>And it should not work. Because you call updateSomeProperty(obj1) from another method of the class and try to change default Transactional behaviour (from REQUIRED to REQUIRED_NEW). But it will not work. Thats why all your changes will be rolled back when exception occurs.</p> <p>By default Spring creates proxy for interface and @Transactional annotation should be used only for public method. And this method should be called from "outside". If you will call them from another method within the class then @Transactional annotation will not work.</p> <p>You can also change default settings for transactions in xml (look at properties proxy-target-class and mode). But I have never changed this and don't remember how exactly it should work.</p> <pre><code>&lt;tx:annotation-driven transaction-manager="txManager" mode="..." proxy-target-class="..."/&gt; </code></pre> <p><strong>EDIT:</strong></p> <p>By the way. Here is a very good <a href="http://www.ibm.com/developerworks/java/library/j-ts1/index.html" rel="nofollow">article about transaction pitfalls</a>. It helped me very much. There are also few other very interesting articles about transactions.</p> <p><strong>EDIT 2:</strong></p> <p>Hello again. I think that I find solution for your problem. At least I tested this and it works for me well. I proposed you to change transaction mode to "AspectJ" and to use AspectJ compile time wieving for project. This will give you a possibility to call a private transactional method from another method within one class with changing transactional behaviour (for started nested transaction). In such case you can commit some changes in nested transaction while outer transaction will be rolled back. For this you need to do such steps:</p> <p>1) Change transaction mode in transactional definition: - if you use xml configuration then:</p> <pre><code>&lt;tx:annotation-driven transaction-manager="txManager" mode="aspectj"/&gt; </code></pre> <ul> <li><p>if you use java configuration then:</p> <p>@EnableTransactionManagement(mode=AdviceMode.ASPECTJ, proxyTargetClass=false)</p></li> </ul> <p>2) Add aspectj dependencies to pom:</p> <pre><code>&lt;dependency&gt; &lt;groupId&gt;org.aspectj&lt;/groupId&gt; &lt;artifactId&gt;aspectjrt&lt;/artifactId&gt; &lt;version&gt;${aspectj.version}&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.aspectj&lt;/groupId&gt; &lt;artifactId&gt;aspectjweaver&lt;/artifactId&gt; &lt;version&gt;${aspectj.version}&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.aspectj&lt;/groupId&gt; &lt;artifactId&gt;aspectjtools&lt;/artifactId&gt; &lt;version&gt;${aspectj.version}&lt;/version&gt; &lt;/dependency&gt; </code></pre> <p>3) Add spring-aspects dependency to pom:</p> <pre><code>&lt;dependency&gt; &lt;groupId&gt;org.springframework&lt;/groupId&gt; &lt;artifactId&gt;spring-aspects&lt;/artifactId&gt; &lt;version&gt;3.1.2.RELEASE&lt;/version&gt; &lt;scope&gt;compile&lt;/scope&gt; &lt;/dependency&gt; </code></pre> <p>4) Add maven plugin that enables compile time wieving:</p> <pre><code> &lt;plugin&gt; &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt; &lt;artifactId&gt;aspectj-maven-plugin&lt;/artifactId&gt; &lt;version&gt;1.4&lt;/version&gt; &lt;configuration&gt; &lt;showWeaveInfo&gt;true&lt;/showWeaveInfo&gt; &lt;source&gt;${compiler.version}&lt;/source&gt; &lt;target&gt;${compiler.version}&lt;/target&gt; &lt;Xlint&gt;ignore&lt;/Xlint&gt; &lt;complianceLevel&gt;${compiler.version}&lt;/complianceLevel&gt; &lt;encoding&gt;UTF-8&lt;/encoding&gt; &lt;verbose&gt;false&lt;/verbose&gt; &lt;aspectLibraries&gt; &lt;aspectLibrary&gt; &lt;groupId&gt;org.springframework&lt;/groupId&gt; &lt;artifactId&gt;spring-aspects&lt;/artifactId&gt; &lt;/aspectLibrary&gt; &lt;/aspectLibraries&gt; &lt;/configuration&gt; &lt;executions&gt; &lt;execution&gt; &lt;goals&gt; &lt;goal&gt;compile&lt;/goal&gt; &lt;!-- &lt;goal&gt;test-compile&lt;/goal&gt; --&gt; &lt;/goals&gt; &lt;/execution&gt; &lt;/executions&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.aspectj&lt;/groupId&gt; &lt;artifactId&gt;aspectjrt&lt;/artifactId&gt; &lt;version&gt;${aspectj.version}&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.aspectj&lt;/groupId&gt; &lt;artifactId&gt;aspectjtools&lt;/artifactId&gt; &lt;version&gt;${aspectj.version}&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;/plugin&gt; </code></pre> <p>5) Also I have maven compiler plugin in my pom thats why I think that it is beter for you to add it too:</p> <pre><code>&lt;plugin&gt; &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt; &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt; &lt;configuration&gt; &lt;compilerVersion&gt;${compiler.version}&lt;/compilerVersion&gt; &lt;fork&gt;true&lt;/fork&gt; &lt;source&gt;1.7&lt;/source&gt; &lt;target&gt;1.7&lt;/target&gt; &lt;/configuration&gt; &lt;/plugin&gt; </code></pre> <p>*Note: I use jdk version 1.7+. And my versions of the compiler and aspectj is sush:</p> <pre><code>&lt;compiler.version&gt;1.7&lt;/compiler.version&gt; &lt;aspectj.version&gt;1.6.12&lt;/aspectj.version&gt; </code></pre> <p>Also I have such versions of other libraries (but I think this is not necessary):</p> <pre><code>&lt;org.springframework.version&gt;3.1.0.RELEASE&lt;/org.springframework.version&gt; &lt;org.hibernate.version&gt;4.1.0.Final&lt;/org.hibernate.version&gt; &lt;org.springdata.version&gt;1.0.2.RELEASE&lt;/org.springdata.version&gt; </code></pre> <p>You also can try to use load time wieving in spring, but it is more hard to configure (this is my opinion) and it is not recommended to be used in production (as I read in few posts). But if you will decide to use it you can find a lot of info in web and spring reference dicumentation.</p> <p>If you want to use compile time wieving without maven then I don't know how to configure this. (I tested only with maven). You can try to find such info in web but I don't recomend this because with maven it is much easier to handle dependencies (and in case of this example - to add necessary plugin). </p> <p>Here is an example that I used for tests:</p> <ul> <li><p>Some interface:</p> <p>public interface TestClassInterface {</p> <pre><code>void testMethod(); </code></pre> <p>}</p></li> <li><p>Some test class that implements this interface:</p> <p>@Transactional(propagation = Propagation.REQUIRED, rollbackFor=Exception.class) @Component public class TestClass implements TestClassInterface {</p> <pre><code>@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); } </code></pre> <p>}</p></li> <li><p>Another class with method that throws exception:</p> <p>public class ExceptionThrower {</p> <pre><code>public void doSomething(Object obj) throws Exception { throw new Exception(); } </code></pre> <p>}</p></li> </ul> <p>Note that I rethrow exception from catch block (I do this as Runtime exception because I don't need to handle it in upper classes). This is necessary for correct outer transaction rollback.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload