【问题标题】:Database deadlock after spock test execuctionspock 测试执行后数据库死锁
【发布时间】:2014-07-24 09:21:56
【问题描述】:

我尝试在 spock 中编写 dbunit 测试,所以我将数据源配置为 postgres 数据库:

@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;
    }

我有两种方法。 @After 一个:

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

前一个:

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

在我的测试 groovy 脚本中,我设置了事务性

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

定义的数据集:

 def data =dataSet {
        //simple data
    };

并给出测试

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

问题是在测试执行后,postgres 数据库出现了一些死锁,并且测试从未完成。可能是代码行 tester.onTearDown();停在提到的死锁上。为了检查它,我执行了查询

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;

返回:

blocked_pid;blocked_user;blocking_pid;blocking_user,blocked_statement 13387;"postgres";13385;"postgres";"权限不足"

任何人都可以帮助我我做错了什么,以及是什么导致了提到的死锁? 谢谢

【问题讨论】:

    标签: postgresql spock dbunit


    【解决方案1】:

    问题是更新或删除数据库开始新事务,在事务结束之前,方法 tester.onTearDown();被称为。 teat down 操作被提及的事务锁定。

    我通过改变解决了描述的问题

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

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

    在完成给定测试的所有事务后进行数据库清理操作。

    【讨论】:

      猜你喜欢
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 2016-05-15
      • 2012-11-14
      • 1970-01-01
      相关资源
      最近更新 更多