New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Oracle Error on creating new Batch Job [BATCH-2475] #1127
Comments
Peter Schäfer commented Hello Guys, would you please answer this bug report. Best, Peter |
Michael Minella commented What additional information can you provide about the use case? I see jobs are being launched from servlets. What more can you tell me about the app and how transactions are handled within the app? |
Peter Schäfer commented Spring Batch is running as a standalone application. curl -Ld 'jobParameters=...' http://...:8080/jobs/SomeJob.json Transactions are handled in a standard fashion, with method annotations Here are a few excerpts from our configuration file: <aop:aspectj-autoproxy proxy-target-class="true" /> ... <batch:job-repository |
Michael Minella commented Where are you using |
Peter Schäfer commented Usually with ItemReaders and ItemWriters, like:
What would be a better way of handling transactions? |
Michael Minella commented Spring Batch handles the transactions automatically so you don't need to do anything. Using |
Peter Schäfer commented I'll give it a try ... Thanks. |
Peter Schäfer commented Tried to remove all The error is easy to reproduce on a newly set-up repository Some people recommend to modify the "initrans" settings - no success, however. |
Peter Schäfer commented None of the recommended work-arounds works reliably. The problem can be reproduced on newly created database schemes, Any more ideas? |
Sebastian Droeppelmann commented We circumvented the error by using two datasources, one for spring batch related commits, one for the actual batch process. Then the error went away. It has to do something with the oracle serialization (who would have guessed :P ) But I found more accounts on this problem (SO) and also encountered it myself. The above mentioned way was the only reliable way to fix this. |
Mz commented
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="databaseType" value="ORACLE"/>
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="isolationLevelForCreate" value="ISOLATION_READ_UNCOMMITTED"/>
</bean> |
Kun liu commented We are bugged by the same error at the moment. Any updates? |
Yavdhesh commented I am stuck with the same problem
@Bean
public JobRepository createJobRepository() throws Exception {
LOG.info("maayne aapana JobRepository maay");
LOG.info("Job Repository being created and isolationLevelForCreate is set to = " + isolationLevelForCreate);
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(primaryDataSource());
factory.setTransactionManager(transactionManager());
LOG.info("Ye transaction manager object hai" + transactionManager());
factory.setIsolationLevelForCreate(isolationLevelForCreate);
factory.setMaxVarCharLength(1000);
factory.setDatabaseType("ORACLE");
return factory.getObject();
} |
Raj Kumar Gupta commented I have got workaround for this issue. Follow below step.
|
This has been asked several times on SO:
And each time people reported that changing the default isolation level (which is That said, according to the feedback on SO, other parameters (like the initrans value, the max pool size, etc) may influence the use case. So I'm closing this issue for now until we are able to reproduce the problem in a reliable way with all parameters included. |
We have same issue using ISOLAION_READ_COMMITTED and it only fails on the first integration test. Seemingly an indicator that the dummy data solution would work. I wonder why though. |
VERY IMPORTANT NOTE: Oracle DOES NOT support ISOLATION_READ_UNCOMMITTED yet this issue is not mentioned anywhere within the Spring documentation. I have had this issue sporadically. To the best of my deduction, it seems that somewhere within the default configuration that Spring starts up as soon as it detects the @EnableBatchProcessing annotation is being used when it attempts to create the new batch job, as opposed to the components that I have configured with ISOLATION_READ_COMMITTED as the default isolation level in Oracle is Serializable. The solution mentioned above regarding the use of multiple datasources makes some sense to me for that specific reason. I am concerned also by the statements I noticed above that indicate that @transactional doesn't play well with batch jobs. As the batch and transaction management capabilities are part of the same framework family that the opposite would be true, that they would be optimized to work together. As far as the insertion of dummy rows is concerned, in later versions of Oracle, I am currently working with 18c, the default allocation setting is to not allocate space until the first insert takes place. Unfortunately, it appears that when the batch is executed for the first time, it seems to cause a a situation where the batch job is competing with the process that is trying to expand the table size and this causes the failure. I forget the exact name of the setting, but your dba's should be able to adjust those table settings appropriately on the Spring Batch management tables. I would like to see more specific information on how to configure a separate datasource specifically for the Spring Batch related commits. |
I was able to track down the issue to the use of "PRIMARY KEY" qualifier in the create table statements in combination with Oracle transaction isolation level "SERIALIZABLE". SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; Root cause: A detailed description of the general issue can be found here: https://asktom.oracle.com/pls/apex/asktom.search?tag=isolation-level-serialization Solution I used Correspondingly I added the same to all "CREATE TABLE" statements for the Spring Batch job repository and things worked fine. |
Thank you very much for this analysis! I'm not expert at oracle, but if this
This would be very important indeed. Do you have any reference to that from the official oracle documentation?
This seems to be accurate based on the reference shared by @grimch, since the default segment creation is |
@benas (I don't know if it is allowed to deep-link Oracle documentation here but by searching for "SET TRANSACTION ISOLATION LEVEL" and going to one off the links of the Oracle Help Center (https://docs.oracle.com/en/) will point you to it.) Note that these isolation levels are for manipulating data. There are "transaction levels" as well for reading data. The respective statements are: So much about doing it interactively, but when using Spring we will usually interact with the database using the java.sql.Connection class either directly or indirectly via some some framework. to get the background l suggest to have a look at this quite interesting article here, which has a section about ANSI isolation level "READ UNCOMMITTED": https://blogs.oracle.com/oraclemagazine/on-transaction-isolation-levels The final proof however that Oracle does not support "java.sql.Connection.TRANSACTION_READ_UNCOMMITTED" you can get with some simple Java test class:
If you run this with
you will get the following exception:
QED. |
@grimch Thank you for your feedback on the supported isolation levels in Oracle, much appreciated! Based on previous comments, I'm re-opening this issue:
|
Hi @benas, Hi All... Just adding my 2 cents here. We have dropped the batch tables and created them with the SEGMENT CREATION IMMEDIATE, and the issue is still persisting. Our Setup so far:
We are running out of ideas 😞 |
@p1xel-dev a) SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; INSERT This is to see if the ORA-08177 error shows up independently of accessing the table via Spring. b) CREATE TABLE test1 ( SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
Hi @grimch, Thanks for your answer. So, I tested a) and it worked correctly using SQLDeveloper. |
Hi, it looks to me that you had executed a) in a table wich already had records in it. If this was the case, then the segment already would have been there and no error was to be expected. If the latter wass the case could you please repeat a) with a fresh set of tables. If you do not want to delete the original ones just modify the respective script and prefix the table names with "x_" for this exercise. |
Hi @grimch, Thanks for the information. I tested it again against BATCH_JOB_INSTANCE_X and a new SEQ and it also worked fine. Data stored correctly no issues shown on SQL Developer. |
Hi @p1xel-dev |
Absolutely. Thank you very much. Just in case, I haven't stated that this issue happens very rarely. Perhaps between 1 and 3 times a day, on a job that runs every 15 mins. |
One more thing for the moment - also of interest for the bigger audience. |
Here are some considerations about the situation described by @p1xel-dev, which is "ORA-08177: can't serialize access for this transaction" occuring during the day to day spring processing and NOT in initial set-up. One aspect of this is that the error shows up even if the transaction level has been set to "TRANSACTION_READ_COMMITTED" in the configuration file. The reason for this seems to be the following:
One way to overcome this (may be there are more elegant ones) would be to override the "createJobRepository()" method in your configuration class and to set the "isolationLevelForCreate" property explicitly
|
@grimch Thank you very much for the insights, we have been monitoring the jobs for the last couple of days and I can confirm that overriding the createJobRepository() method and passing the isolation level has fixed the issue we were facing. |
Peter Schäfer opened BATCH-2475 and commented
When launching a Batch Job, the following exception is thrown:
2016-02-18 03:20:01.686 ERROR 16635 --- [nio-8082-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.CannotSerializeTransactionException: PreparedStatementCallback; SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; ORA-08177: can't serialize access for this transaction
; nested exception is java.sql.SQLException: ORA-08177: can't serialize access for this transaction
] with root cause
java.sql.SQLException: ORA-08177: can't serialize access for this transaction
See attached stack trace.
The error is hard to reproduce.
We tried the following work-around:
<batch:job-repository id="jobRepository"
...isolation-level-for-create="READ_COMMITTED"
... />
with little success.
Affects: 3.0.6
Reference URL: https://stackoverflow.com/questions/22364432/spring-batch-ora-08177-cant-serialize-access-for-this-transaction-when-running
Attachments:
6 votes, 11 watchers
The text was updated successfully, but these errors were encountered: