Search code examples
postgresqlspockdbunit

Database deadlock after spock test execuction


I try to write dbunit test in spock, so I configured datasource to postgres database:

@Bean
    public DataSource dataSource() {
        PGSimpleDataSource source = new PGSimpleDataSource();
        source.setServerName(environment.getProperty("db.test.server.name"));
        source.setDatabaseName(environment.getProperty("db.test.database.name"));
        source.setUser(environment.getProperty("db.test.user.name"));
        source.setPassword(environment.getProperty("db.test.user.password"));

        return source;
    }

I have two methods. The @After one:

def setup() {
        tester = new DataSourceDatabaseTester(dataSource)
        tester.setSchema("schema")
        tester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT)
        tester.setTearDownOperation(DatabaseOperation.CLEAN_INSERT)
    }

and before one:

def cleanup() {
        tester.onTearDown();
    }

In my test groovy script I have set transactional

@Transactional(propagation = Propagation.REQUIRES_NEW)
class SimpleDaoTest extends CommonTestSetup{

defined dataset:

 def data =dataSet {
        //simple data
    };

and given test

@Test
@Rollback
void test(){
    //update operation
    //select operation
    //some check
}

Problem is that after test execution there is some deadlock on postgres database and test has never finished. Probably the code line tester.onTearDown(); stops on mentioned deadlock. To check it I executed query

SELECT bl.pid     AS blocked_pid,
         a.usename  AS blocked_user,
         kl.pid     AS blocking_pid,
         ka.usename AS blocking_user,
         a.query    AS blocked_statement
   FROM  pg_catalog.pg_locks         bl
    JOIN pg_catalog.pg_stat_activity a  ON a.pid = bl.pid
    JOIN pg_catalog.pg_locks         kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid
    JOIN pg_catalog.pg_stat_activity ka ON ka.pid = kl.pid
   WHERE NOT bl.granted;

which returned:

blocked_pid;blocked_user;blocking_pid;blocking_user,blocked_statement 13387;"postgres";13385;"postgres";"insufficient privilege"

Can anybody help me what I am doing wrong, and what causes mentioned deadlock? Thanks


Solution

  • Problem was that update or delete on database start new transaction, and before transaction was end, method tester.onTearDown(); was called. The teat down action was locked by mentionned transactions.

    I sovled described problem by changing

    def cleanup() {
            tester.onTearDown();
        }
    

    by

    @AfterTransaction
        def cleanDatabase(){
            tester.onTearDown();
        }
    

    Database cleaning operation is made after finished all transactions on given test.