cancel
Showing results for 
Search instead for 
Did you mean: 

runtimeService.getVariables requires a ReadW

billy_mcdonagh
Champ in-the-making
Champ in-the-making
Hi, I'm using Activiti 5.1.4 with Spring 4.1.5.RELEASE and Hibernate 4.1.9.Final and I'm getting the following issue 'cannot execute UPDATE in a read-only transaction' (stacktrace below) when calling the RuntimeService.getVariables() method. My service method containing the call to the RuntimeService is annotated with the following:

@Transactional(readOnly = true, propagation = Propagation.REQUIRED)

If the readOnly attribute is changed to readOnly=false so it creates a read write transaction, the call to RuntimeService.getVariables() works fine. Is this the expected behaviour that updates are flushed even for a readonly call such as getVariables?
Thanks in  advance.

StackTrace:

ERROR:  cannot execute UPDATE in a read-only transaction
[postgres error] STATEMENT:  update ACT_GE_BYTEARRAY
[postgres error]        set
[postgres error]          REV_ = $1,
[postgres error]          BYTES_ = $2
[postgres error]        where ID_ = $3
[postgres error]          and REV_ = $4
[postgres error] 2015-10-20 10:28:29,077 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] - <SQL Error: 0, SQLState: 25006>
2015-10-20 10:28:29,077 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] - <ERROR: cannot execute UPDATE in a read-only transaction>
2015-10-20 10:28:29,079 ERROR [org.activiti.engine.impl.interceptor.CommandContext] - <Error while closing command context>
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database.  Cause: org.hibernate.exception.GenericJDBCException: ERROR: cannot execute UPDATE in a read-only transaction
### The error may involve org.activiti.engine.impl.persistence.entity.ByteArrayEntity.updateByteArray_postgres-Inline
### The error occurred while setting parameters
### SQL: update ACT_GE_BYTEARRAY      set       REV_ = ?,       BYTES_ = ?     where ID_ = ?       and REV_ = ?
### Cause: org.hibernate.exception.GenericJDBCException: ERROR: cannot execute UPDATE in a read-only transaction
   at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)
   at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:150)
   at org.activiti.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:560)
   at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:444)
   at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:170)
   at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:117)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66)
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
   at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
   at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
   at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
   at org.activiti.engine.impl.RuntimeServiceImpl.getVariables(RuntimeServiceImpl.java:108)
3 REPLIES 3

jbarrez
Star Contributor
Star Contributor
No, the getVariables() should do any update. But the fact it's a byteArray … could it be you have Serialized java objects as variables? That might explain it.
Out of curiosity: whats the use for demarcating your transactions so strictly?

Thanks for your quick response 🙂

Yes we do have Java objects as variables so this makes sense.
Probably a silly question but what updates would activity be flushing for a call to getVariables()?

The reason we have the transactions so strict is because according to the Spring Documentation (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#transacti...) if using Hibernate setting a transaction as read-only allows it to do some optimisation
….
Read-only status: A read-only transaction can be used when your code reads but does not modify data. Read-only transactions can be a useful optimization in some cases, such as when you are using Hibernate.
…..

Also it is useful if another developer wrongly modifies a service method that is understood to only perform readonly actions. If marked as readonly an exception will be thrown which will hopefully highlight the issue.

Thanks.
Billy.

jbarrez
Star Contributor
Star Contributor
> Probably a silly question but what updates would activity be flushing for a call to getVariables()?

Not a silly question, I was pondering about that myself 😉 I guess for Java object serialization some 'touching' is going on, even if it's just a 'get'.


Ok, thanks for the readonly explanation. I've never saw it being used in practice.