{"id":1405,"date":"2010-07-30T13:31:37","date_gmt":"2010-07-30T08:01:37","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=1405"},"modified":"2010-08-04T15:20:24","modified_gmt":"2010-08-04T09:50:24","slug":"grails-transactions-using-transactional-annotations-and-propagation-requires_new","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/grails-transactions-using-transactional-annotations-and-propagation-requires_new\/","title":{"rendered":"Grails Transactions using @Transactional annotations and Propagation.REQUIRES_NEW"},"content":{"rendered":"<p>Hi All,<\/p>\n<p>Here is how you can implement a new transaction in an already executing transaction in Grails which uses nothing but Spring framework&#8217;s Transaction mechanism as an underlying implementation. Spring provides <strong><em>@Transactional <\/em><\/strong>annotations to provide declarative transactions. We can use the same in our Grails project to achieve the transactional behavior.<\/p>\n<p><em>Here is the scenario:<\/em> You have two domain classes named <strong>SecuredAccount<\/strong> and <strong>AccountCreationAttempt<\/strong>. You try to transactionally save the SecuredAccount object which in turn creates a AccountCreationAttempt object which writes to the database stating: &#8220;There is an attempt to create a new SecuredAccount at this time: &lt;current date and time&gt;&#8221;. Point to note here is that even if the creation of the new SecuredAccount object fails, the record must still be written to the database so that the Administrator can validate whether the attempt at the specific time was by a legitimate user or an attacker. <\/p>\n<p><em>Here is the code:<\/em><\/p>\n<pre lang=\"groovy\">import org.springframework.transaction.annotation.*\r\nClass MyService {\r\n\r\nstatic transactional = false\r\ndef anotherService\r\n\r\n@Transactional\r\ndef createSecuredAccount() {\r\ndef securedAccount = new SecuredAccount(userId:\"John\")\r\nsecuredAccount.save(flush:true)\r\nanotherService.createAccountCreationAttempt()\r\nthrow new RuntimeException(\"Error thrown in createSecuredAccount()\")\r\n}\r\n}\r\n<\/pre>\n<pre lang=\"groovy\">import org.springframework.transaction.annotation.*\r\nclass AnotherService {\r\n\r\nstatic transactional = false\r\n\r\n@Transactional(propagation = Propagation.REQUIRES_NEW)\r\ndef createAccountCreationAttempt() {\r\ndef accountCreationAttempt = new AccountCreationAttempt(logRemarks: \"There is an attempt to create a new SecuredAccount at this time: {new Date()}\")\r\naccountCreationAttempt.save(flush:true)\r\n}\r\n}\r\n<\/pre>\n<p>Now in this scenario, AccountCreationAttempt object always gets persisted whether or not the transaction for creating SecuredAccount object fails.<\/p>\n<p>Here are few gotchas regarding the above transactions:<\/p>\n<p>1.) First of all, for <em>Propagation.REQUIRES_NEW <\/em>to work as intended, it has to be inside a new object i.e. a new service in our example. If we had put the <em>createAccountCreationAttempt()<\/em> method in the MyService there would be no new transaction spawned and even no log entry would be made. This is Spring&#8217;s proxy object implementation of transactions and you can read more about it here:<\/p>\n<p><a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.0.x\/spring-framework-reference\/html\/transaction.html#transaction-declarative-annotations\" target=\"_blank\">http:\/\/static.springsource.org\/spring\/docs\/3.0.x\/spring-framework-reference\/html\/transaction.html#transaction-declarative-annotations<\/a>.<\/p>\n<p>Please pay special attention to the &#8220;<strong>NOTE<\/strong>&#8221; sub-section.This is what it states:<\/p>\n<p>&#8220;In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with<em><strong> @Transactional<\/strong><\/em>.&#8221;<\/p>\n<p>2.) Secondly, all the <em><strong>@Transactional<\/strong><\/em> methods should have a public visibility i.e. createSecuredAccount() and createAccountCreationAttempt() methods should be public methods, and not private or protected. This again is Spring&#8217;s <em><strong>@Transactional<\/strong> <\/em>annotations implementation and you can read about it at the same <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.0.x\/spring-framework-reference\/html\/transaction.html#transaction-declarative-annotations\" target=\"_blank\">link<\/a> as provided above. Note the right side-bar titled &#8220;<strong>Method visibility and <em>@Transactional<\/em><\/strong>&#8220;.<\/p>\n<p>Well, once you keep note of these gotchas I guess you are all set to make good use of <strong><em>@Transactional<\/em><\/strong> annotations and its full power.<\/p>\n<p>Cheers !!!<\/p>\n<p>&#8211; Abhishek Tejpaul<br \/>\nabhishek@intelligrape.com<br \/>\n[IntelliGrape Software Pvt. Ltd.]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi All, Here is how you can implement a new transaction in an already executing transaction in Grails which uses nothing but Spring framework&#8217;s Transaction mechanism as an underlying implementation. Spring provides @Transactional annotations to provide declarative transactions. We can use the same in our Grails project to achieve the transactional behavior. Here is the [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":32},"categories":[7],"tags":[348,350,352,349,351,353],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/1405"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=1405"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/1405\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=1405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=1405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=1405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}