What is a Grails "transactional" service? - grails

I'm reading the Grails docs on services which make numerous mention of transactions/transactionality, but without really defining what a transactional service method really is.
Given the nature of services, they frequently require transactional behaviour.
What exactly does this mean? Are transactional methods only those that use JPA/JDBC to communicate with a relational DB, or do they apply to anything covered by JTA?
Is there any reason why I just wouldn't make a service class #Transactional in case it evolves to some day use a transaction? In other words, are there performance concerns to making all service methods transactional?

Grails services are transactional by default - if you don't want a service to be transactional, you need to remove all #Transactional annotations (both Grails' #grails.transaction.Transactional and Spring's #org.springframework.transaction.annotation.Transactional) and add
static transactional = false
If you haven't disabled transactions with the transactional property and have no annotations, the service works the same as if it were annotated with Spring's annotation. That is, at runtime Spring creates a CGLIB proxy of your class and registers an instance of the proxy as the Spring bean, and it delegates to an instance of your actual class to do the database access and your business logic. This lets the proxy intercept all public method calls and start a new transaction, join an existing one, create a new one, etc.
The newer Grails annotation has all of the same settings as the Spring annotation, but it works a bit differently. Instead of triggering the creation of a single proxy, each method is rewritten by an AST transform during compilation, essentially creating a mini proxy for each method (this is obviously a simplification). This is better because the database access and transaction semantics are the same, but if you call one annotated method from another annotated with different settings, the different settings will be respected. But with a proxy, it's a direct call inside the delegate instance, and the proxy is bypassed. Since the proxy has all of the logic to create a new transaction or use other different settings, the two methods will use the first method's settings. With the Grails annotation every method works as expected.
There is a small performance hit involved for transactional methods, and this can accumulate if there are a lot of calls and/or a lot of traffic. Before your code runs, a transaction is started (assuming one isn't active) and to do this, a connection must be retrieved from the pool (DataSource) and configured to turn off autocommit, and make the various transaction settings (isolation, timeout, readonly, etc.) have to be made. But the Grails DataSource is actually a smart wrapper around the "real" one. It doesn't get a real JDBC Connection until you start a query, so all of the configuration settings are cached until then, and then "replayed" on the real connection. If the method doesn't do any database work (either because it never does, or because it exits early based on some condition before the db access code fires), then there's basically no database cost. But if it does, then things work as expected.
Don't rely on this DataSource proxying logic though - it's best to be explicit about which services are transactional and which aren't, and within each service which methods are transactional and which aren't. The best way to do this is by annotating methods as needed, or adding a single annotation at the class level if all methods use the same settings.
You can get more info in this talk I did about transactions in Grails.

First, if your performance concerns are due to the fact your services are transactional then you have reached nirvana. I say this because there are going to be plenty of other bottle necks in your application long before this is a major (or even minor) concern. So, don't fret about that.
Typically in Grails a transaction relates to the transactional state of a database connection or hibernate session. Though it could be anything managed by the JTA with the proper Spring configuration.
In simple terms, it's usually means (by default) a database transaction.

Related

How to peek at message while dependencies are being built?

I building multitenancy into the unit of work for a set of services. I want to keep the tenancy question out of the way of day-to-day business domain work, and I do not want to touch every existing consumer in the system (I am retrofitting the multitenancy onto a system without any prior concept of a tenant).
Most messages in the system will be contexted by a tenant. However, there will be some infrastructure messages which will not be, particularly for the purpose of automating tenant creation. I need a way of determining whether to use a tenant-contexted unit of work, or a infrastructure unit of work uncontexted by a tenant because the way I interact with the database is different depending on whether I have tenant context. The unit of work is built in the process of spinning up the dependencies of the consumer.
As such I need a way of peeking at the message or its metadata before consuming it, and specifically, I need to be able to peek at it during the dependency building. I was intended to have a tag interface to mark tenant management messages out from normal business domain messages, but any form of identifying the difference could work. If I am in a unit of work resulting from an HTTP request, I can look at WebApi's HttpContext.Current and see the headers of the current request, etc. How do I do something analogous to this if I am in a unit of work resulting from messaging?
I see there is a way to intercept messages with BeforeConsumingMessage() but I need a way of correlating it to the current unit of work I am spinning up and I'm not seeing how that would work for me. Pseudocode for what I am trying to do:
if MessageContext.Message.GetType() = typeof<ITenantInfrastructureMessage>:
database = new Database(...)
else:
tenantId = MessageContext.Headers.TenantId;
database = new TenantDatabase(..., tenantId)
I am working in C#/.NET using MassTransit with RabbitMQ and Autofac with MassTransit's built-in support for both.
Your best option is to override at the IConsumerFactory<T> extension point, and extract the tenant from the message (either via a message header, or some message property) and register that in the container child lifetime scope so that subsequent resolutions from the actual consumer class (and it's dependencies) are properly matched to the tenant in the message.
In our systems, we have a TenantContext that is registered in a newly created LifetimeScope (we're using Autofac), after which we resolve the consume from the child scope, and the dependencies that use the tenant context get the proper value since it's registered as part of building the child container for the message scope.
It works extremely well, we even built up extension methods to make it easy for developers registering consumers to specify "tenant context providers" that go from a message type to the proper tenant id, which is used to build the TenantContext.
You can do similar things with activity factories in Courier routing slips (which are a specialization of a consumer).

How can I tell how many database connections my application is using?

I have a grails web application which is connecting to a Postgres database. I'm concerned that the code is opening multiple database connections.
How can I find out how many connections it is holding during a request?
There's a lot of magic going on in there with GORM etc and I'm not sure how it's managing its connections.
It's managed by the dataSource bean, which is a javax.sql.DataSource. Unfortunately this interface is very basic, with only 4 methods - 2 getConnection() methods (one with and one without a username/password) and unwrap and isWrapperFor from its parent interface. The actual implementation classes typically have many different methods for configuration and monitoring, but there isn't really any standard, and definitely no interface.
If you're using a recent version of Grails and haven't reconfigured anything, the backing implementation is the Tomcat JDBC Pool, which doesn't depend on Tomcat but was written by a Tomcat committer. You can't just cast that bean to the pool implementation class however, because Grails wraps the actual datasource instance in two proxies. Fortunately the "real" instance is easy to get to - dependency-inject the dataSourceUnproxied bean in a service or wherever you wanted to look at usage:
def dataSourceUnproxied
and then you can call any of its methods (see the Javadoc for what's available)
It's not needed for Groovy of course, but if you want IDE autocompletion add this import
import org.apache.tomcat.jdbc.pool.DataSource
and cast it and call the methods on that, e.g.
DataSource tomcatDataSource = dataSourceUnproxied
log.debug "$tomcatDataSource.active active (max $tomcatDataSource.maxActive, initial $tomcatDataSource.initialSize), $tomcatDataSource.idle idle (max $tomcatDataSource.maxIdle, min $tomcatDataSource.minIdle)"

Using private fields in the grails controller

I know that service in grails is singleton by default.
Is it bad practice to use private fields in controller/service? Could anyone explain, why?
Controllers are not singletons by default. They are created for each request. Services are, by default singletons. It's not bad practice to use private fields in Services. It's fairly common that Services have private fields to hold configuration state at runtime.
I suspect your concern is about using private fields as a means of storing state for a particular request within a Service. Which is obviously bad considering there could be N requests being serviced by the Service. So long as you are using private fields to control the service from an application perspective and not a request perspective you will be fine.
Edit (further information)
As stated, services can and often do have private members. However, you should never use these as a means for storing information about the current request being processed. Obviously, since this is a singleton that would cause interleaving issues. Only use private members to store information that is visible across all requests. Typically these will be configuration settings of the service itself.
It's best to make your service stateless in regards to the requests they are processing. Any state you need should be encapsulated in the parameter(s) or input/output of your Service methods. Services should act on data, not the other way around.

CXF client loads wsdl for both service and port?

In a java web app, I need to call a remote soap service, and I'm trying to use a CXF 2.5.0-generated client. The soap service is provided by a particular ERP vendor, and its wsdl is monstrous, thousands of types, dozens of xsd imports, etc. wsdl2java generates the client ok, thanks to the -autoNameResolution flag. But at runtime it retrieves the remote wsdl twice, once when I create the service object, and again when I create a port object.
MyService_Service myService = new MyService_Service(giantWsdlUrl); // fetches giantWsdl
MyService myPort = myService.getMyServicePort(); // fetches giantWsdl again
Why is that? I can understand retrieving it when creating myService, you want to see that it matches the client I'm currently using, or let a runtime wsdl location dictate the endpoint address, etc. But I don't understand why asking for the port would reload everything it just went out on the wire for. Am I missing something?
Since this is in a web application, and I can't be sure that myPort is threadsafe, then I'd have to create a port for each thread, except that's way too slow, 6 to 8 seconds thanks to the monstrous wsdl. Or add my own pooling, create a bunch in advance, and do check-outs and check-ins. Yuck.
For the record, the JaxWsProxyFactoryBean creation route does not ever fetch the wsdl, and that's good for my situation. It still takes a long time on the first create(), then about a quarter second on subsequent create()s, and even that's less than desirable. And I dunno... it sorta feels like I'm under the hood hotwiring the thing rather than turning the key. :)
Well, you have actually answered the question yourself. Each time you invoke service.getPort() the WSDL is loaded from remote site and parsed. JaxWsProxyFactoryBean goes absolutely the same way, but once the proxy is obtained it is re-used for further invocations. That is why the 1st run is slow (because of "warming up"), but subsequent are fast.
And yes, JaxWsProxyFactoryBean is not thread-safe. Pooling client proxies is an option, but unfortunately will eat a lot of memory, as JAX-WS runtime model is not shared among client proxies; synchronization is perhaps better way to follow.

Spring.NET, Quartz & Transactions

I've just run into a problem with a Quartz job that I'm invoking through Spring. My ExecuteInternal method had a [Transaction] attribute (because it does a load of DB calls) but when it runs, I get the 'No NHibernate session bound to thread' error.
Just wondering if that's because Spring.NET doesn't support the [Transaction] attribute in Quartz objects?
If not, that's fine... I can start a transaction manually, but wanted to check that it was the case, and not a silly error in my config somewhere.
[Update]
I figured it out actually. In the API docs, it says the preferable way to do this is use transactions on the service layer. My job was using DAOs to do its work, but my transactions are on my service layer, so I just called service methods from my job instead to do the same work (saving, updating records etc) since they already existed.
It also suggests that if you give the SchedulerFactoryObject a DbProvider, you can use transactions in the job itself, but when I did that it seemed to want to find my triggers configured in a special table in the DB (which I haven't set up since my triggers are all in XML) but that's possibly another way to do it.
Calling service methods works fine for me though.
The transaction attribute works using aop. Spring.NET creates an aop proxy for the decorated object. This proxy creates the session and starts the transaction.
In the ExecuteInternal method, you don't call the method on a proxy, but on the target itself. Therefore spring cannot intercept the call and do its transaction magic.
Your services are injected and therefore the transaction attribute works for them.
There's a good explanation in the spring docs on this subject: http://www.springframework.net/doc-latest/reference/html/transaction.html#tx-understandingimpl

Resources