Ticket #698 (closed Enhancement: fixed)
Plugin framework: create transactions by annotation
Reported by: | jri | Owned by: | jri |
---|---|---|---|
Priority: | Major | Milestone: | Release 4.4 |
Component: | DeepaMehta Standard Distribution | Version: | 4.3 |
Keywords: | Cc: | dgf, Malte, carolina | |
Complexity: | 5 | Area: | Application Framework / API |
Module: | deepamehta-core |
Description
The plugin developer should not be required to create transactions imperatively. Instead she should create a transaction just by annotating a resource method. (A resource method is one with a method designator like @GET.) The DM Core should take provisions to "wrap" such an annotated method within a transaction automatically.
Current pattern (DM 4.3):
import de.deepamehta.core.storage.spi.DeepaMehtaTransaction; public void aResourceMethod() { DeepaMehtaTransaction tx = dms.beginTx(); try { ... tx.success(); } catch (Exception e) { logger.warning("ROLLBACK!"); throw new RuntimeException("Something failed", e); } finally { tx.finish(); } }
New pattern:
import de.deepamehta.core.service.Transactional; @Transactional public void aResourceMethod() { ... }
So, the new pattern would remove a reasonable amount of boilerplate code.
Change History
comment:2 Changed 10 years ago by Jörg Richter
Core: create transactions by annotation (#698).
A plugin developer can create a transaction just by annotating a resource method. (A resource method is one with a method designator like @GET.) The DM Core takes provisions to "wrap" such an annotated method within a transaction automatically.
Example:
import de.deepamehta.core.service.Transactional; @Transactional public void aResourceMethod() { ... }
See #698.
comment:3 Changed 10 years ago by Jörg Richter
Adapt to Core change (@Transactional) (#698).
The DM distro plugins make use of the new @Transactional annotation.
PLUGIN DEVELOPMENT NOTES
Keep in mind that the Core Service methods (called via the dms object) do not create a transaction on its own anymore (but the corresponding resource methods of the Webservice plugin do). So, when your plugin encounters a NotInTransactionException exception just annotate your originally calling resource method with @Transactional. (A resource method is one with a method designator like @GET.)
Example:
import de.deepamehta.core.service.Transactional; @Transactional public void aResourceMethod() { ... }
Note that the majority of your plugin methods are triggered originally by an HTTP request (directly or indirectly), that is a resource method. Annotating that resource method is sufficient. (In fact @Transactional annotations on non-resource methods are ignored.) Most plugins are not required to create a transaction imperatively anymore.
However, there are cases when your plugin methods are *not* triggered by a HTTP request. These cases include
- the allPluginsActive() event handler
- tests
- DM service calls from non-DM OSGi bundles
In these cases you're required to create the transaction imperatively, just as you did before:
import de.deepamehta.core.storage.spi.DeepaMehtaTransaction; public void aMethod() { DeepaMehtaTransaction tx = dms.beginTx(); try { ... tx.success(); } catch (Exception e) { logger.warning("ROLLBACK!"); throw new RuntimeException("Something failed", e); } finally { tx.finish(); } }
Note: calling a @Transactional annotated resource method from another @Transactional annotated resource method is OK. No nested transaction will be created. (Nested transactions are not problematic anyway.) Keep in mind a transaction is only created for the resource method the original HTTP request is mapped to. So, typically there is a 1:1 relationship between transaction and HTTP request.
See #698.
comment:4 Changed 10 years ago by Jörg Richter
Core: create transactions by annotation (#698).
A plugin developer can create a transaction just by annotating a resource method. (A resource method is one with a method designator like @GET.) The DM Core takes provisions to "wrap" such an annotated method within a transaction automatically.
Example:
import de.deepamehta.core.service.Transactional; @Transactional public void aResourceMethod() { ... }
See #698.
comment:5 Changed 10 years ago by Jörg Richter
Adapt to Core change (@Transactional) (#698).
The DM distro plugins make use of the new @Transactional annotation.
PLUGIN DEVELOPMENT NOTES
Keep in mind that the Core Service methods (called via the dms object) do not create a transaction on its own anymore (but the corresponding resource methods of the Webservice plugin do). So, when your plugin encounters a NotInTransactionException exception just annotate your originally calling resource method with @Transactional. (A resource method is one with a method designator like @GET.)
Example:
import de.deepamehta.core.service.Transactional; @Transactional public void aResourceMethod() { ... }
Note that the majority of your plugin methods are triggered originally by an HTTP request (directly or indirectly), that is a resource method. Annotating that resource method is sufficient. (In fact @Transactional annotations on non-resource methods are ignored.) Most plugins are not required to create a transaction imperatively anymore.
However, there are cases when your plugin methods are *not* triggered by a HTTP request. These cases include
- the allPluginsActive() event handler
- tests
- DM service calls from non-DM OSGi bundles
In these cases you're required to create the transaction imperatively, just as you did before:
import de.deepamehta.core.storage.spi.DeepaMehtaTransaction; public void aMethod() { DeepaMehtaTransaction tx = dms.beginTx(); try { ... tx.success(); } catch (Exception e) { logger.warning("ROLLBACK!"); throw new RuntimeException("Something failed", e); } finally { tx.finish(); } }
Note: calling a @Transactional annotated resource method from another @Transactional annotated resource method is OK. No nested transaction will be created. (Nested transactions are not problematic anyway.) Keep in mind a transaction is only created for the resource method the original HTTP request is mapped to. So, typically there is a 1:1 relationship between transaction and HTTP request.
See #698.
comment:6 Changed 10 years ago by Jörg Richter
Core: create transactions by annotation (#698).
A plugin developer can create a transaction just by annotating a resource method. (A resource method is one with a method designator like @GET.) The DM Core takes provisions to "wrap" such an annotated method within a transaction automatically.
Example:
import de.deepamehta.core.service.Transactional; @Transactional public void aResourceMethod() { ... }
See #698.
comment:7 Changed 10 years ago by Jörg Richter
Adapt to Core change (@Transactional) (#698).
The DM distro plugins make use of the new @Transactional annotation.
PLUGIN DEVELOPMENT NOTES
Keep in mind that the Core Service methods (called via the dms object) do not create a transaction on its own anymore (but the corresponding resource methods of the Webservice plugin do). So, when your plugin encounters a NotInTransactionException exception just annotate your originally calling resource method with @Transactional. (A resource method is one with a method designator like @GET.)
Example:
import de.deepamehta.core.service.Transactional; @Transactional public void aResourceMethod() { ... }
Note that the majority of your plugin methods are triggered originally by an HTTP request (directly or indirectly), that is a resource method. Annotating that resource method is sufficient. (In fact @Transactional annotations on non-resource methods are ignored.) Most plugins are not required to create a transaction imperatively anymore.
However, there are cases when your plugin methods are *not* triggered by a HTTP request. These cases include
- the allPluginsActive() event handler
- tests
- DM service calls from non-DM OSGi bundles
In these cases you're required to create the transaction imperatively, just as you did before:
import de.deepamehta.core.storage.spi.DeepaMehtaTransaction; public void aMethod() { DeepaMehtaTransaction tx = dms.beginTx(); try { ... tx.success(); } catch (Exception e) { logger.warning("ROLLBACK!"); throw new RuntimeException("Something failed", e); } finally { tx.finish(); } }
Note: calling a @Transactional annotated resource method from another @Transactional annotated resource method is OK. No nested transaction will be created. (Nested transactions are not problematic anyway.) Keep in mind a transaction is only created for the resource method the original HTTP request is mapped to. So, typically there is a 1:1 relationship between transaction and HTTP request.
See #698.