Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8657231
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T15:28:15+00:00 2026-06-12T15:28:15+00:00

maybe somebody can help me with a transactional issue in Spring (3.1)/ Postgresql (8.4.11)

  • 0

maybe somebody can help me with a transactional issue in Spring (3.1)/ Postgresql (8.4.11)

My transactional service is as follows:

@Transactional(isolation = Isolation.SERIALIZABLE, readOnly = false)
@Override
public Foo insertObject(Bar bar) {

            // these methods are just examples
            int x = firstDao.getMaxNumberOfAllowedObjects(bar)
            int y = secondDao.getNumerOfExistingObjects(bar)
            // comparison
            if (x - y > 0){
                  secondDao.insertNewObject(...) 
            }
            ....
}

The Spring configuration Webapp contains:

@Configuration 
@EnableTransactionManagement 
public class ....{
    @Bean
    public DataSource dataSource() {
        org.apache.tomcat.jdbc.pool.DataSource ds = new DataSource();

        ....configuration details

        return ds;
    }

    @Bean
    public DataSourceTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

Let us say a request “x” and a request “y” execute concurrently and arrive both at the comment “comparison” (method insertObject). Then both of them are allowed to insert a new object and their transactions are commited.

Why am I not having a RollbackException? As far as I know that is what the Serializable isolotation level is for. Coming back to the previous scenario, if x manages to insert a new object and commits its transaction, then “y”‘s transaction should not be allowed to commit since there is a new object he did not read.

That is, if “y” could read again the value of secondDao.getNumerOfExistingObjects(bar) it would realize that there is a new object more. Phantom?

The transaction configuration seems to be working fine:

  • For each request I can see the same connection for firstDao and secondDao
  • A transaction is created everytime insertObject is invoked

Both first and second DAOs are as follows:

@Autowired
public void setDataSource(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource);
}

@Override
public Object daoMethod(Object param) {

        //uses jdbcTemplate

}

I am sure I am missing something. Any idea?

Thanks for your time,

Javier

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T15:28:16+00:00Added an answer on June 12, 2026 at 3:28 pm

    TL;DR: Detection of serializability conflicts improved dramatically in Pg 9.1, so upgrade.


    It’s tricky to figure out from your description what the actual SQL is and why you expect to get a rollback. It looks like you’ve seriously misunderstood serializable isolation, perhaps thinking it perfectly tests all predicates, which it doesn’t, especially not in Pg 8.4.

    SERIALIZABLE doesn’t perfectly guarantee that the transactions execute as if they were run in series – as doing so would be prohibitively expensive from a performance point of view if it it were possible at all. It only provides limited checking. Exactly what is checked and how varies from database to database and version to version, so you need to read the docs for your version of your database.

    Anomalies are possible, where two transactions executing in SERIALIZABLE mode produce a different result to if those transactions truly executed in series.

    Read the documentation on transaction isolation in Pg to learn more. Note that SERIALIZABLE changed behaviour dramatically in Pg 9.1, so make sure to read the version of the manual appropriate for your Pg version. Here’s the 8.4 version. In particular read 13.2.2.1. Serializable Isolation versus True Serializability. Now compare that to the greatly improved predicate locking based serialization support described in the Pg 9.1 docs.

    It looks like you’re trying to perform logic something like this pseudocode:

    count = query("SELECT count(*) FROM the_table");
    if (count < threshold):
        query("INSERT INTO the_table (...) VALUES (...)");
    

    If so, that’s not going to work in Pg 8.4 when executed concurrently – it’s pretty much the same as the anomaly example used in the documentation linked above. Amazingly it actually works on Pg 9.1; I didn’t expect even 9.1’s predicate locking to catch use of aggregates.

    You write that:

    Coming back to the previous scenario, if x manages to insert a new
    object and commits its transaction, then “y”‘s transaction should not
    be allowed to commit since there is a new object he did not read.

    but 8.4 won’t detect that the two transactions are interdependent, something you can trivially prove by using two psql sessions to test it. It’s only with the true-serializability stuff introduced in 9.1 that this will work – and frankly, I was surprised it works in 9.1.

    If you want to do something like enforce a maximum row count in Pg 8.4, you need to LOCK the table to prevent concurrent INSERTs, doing the locking either manually or via a trigger function. Doing it in a trigger will inherently require a lock promotion and thus will frequently deadlock, but will successfully do the job. It’s better done in the application where you can issue the LOCK TABLE my_table IN EXCLUSIVE MODE before obtaining even SELECTing from the table, so it already has the highest lock mode it will need on the table and thus shouldn’t need deadlock-prone lock promotion. The EXCLUSIVE lock mode is appropriate because it permits SELECTs but nothing else.

    Here’s how to test it in two psql sessions:

    SESSION 1                               SESSION 2
    
    create table ser_test( x text );
    
    BEGIN TRANSACTION 
    ISOLATION LEVEL SERIALIZABLE;
    
    
                                            BEGIN TRANSACTION 
                                            ISOLATION LEVEL SERIALIZABLE;
    
    SELECT count(*) FROM ser_test ;
    
                                            SELECT count(*) FROM ser_test ;
    
    INSERT INTO ser_test(x) VALUES ('bob');
    
    
                                            INSERT INTO ser_test(x) VALUES ('bob');
    
     COMMIT;
    
                                            COMMIT;
    

    When run on Pg 9.1, the st commits succeeds then the secondCOMMIT` fails with:

    regress=# COMMIT;
    ERROR:  could not serialize access due to read/write dependencies among transactions
    DETAIL:  Reason code: Canceled on identification as a pivot, during commit attempt.
    HINT:  The transaction might succeed if retried.
    

    but when run on 8.4 both commits commits succeed, because 8.4 didn’t have all the predicate locking code for serializability added in 9.1.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Maybe somebody can help me. Starting with a CSV file like so: Ticker,Price,Market Cap
Maybe somebody can help me. In my project I'm using a linked list with
Maybe somebody can help explain why I am getting a null value when converting
UPDATE AT THE BOTTOM Maybe somebody could help with this... been struggling with it
I have some problems with the understanding of casting buttons, maybe you can help
can somebody help me select the url from this XML document where the ID
maybe I will not correct explain a problem, maybe somebody help me explain this
Probably staying late fixing a few bugs tonight, but maybe SO can help me
I am having some trouble with this regular expression, Can somebody maybe assist me
Maybe I just can't figure out the right keywords to get an answer out

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.