2

我们每天午夜从 CI 运行 Junit 和 Selenium 测试用例。我们使用 Maven-SQL 插件预填充数据,如下所示。

          <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>sql-maven-plugin</artifactId>
                <version>1.3</version>
                <executions>
                    <execution>
                        <id>create-database-tables</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <autocommit>false</autocommit>
                            <onError>continue</onError>
                            <srcFiles>
                                <srcFile>../sql/delete_data.sql</srcFile>
                                <srcFile>../sql/load_data.sql</srcFile>
                            </srcFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

由于不同用户同时构建,我们经常面临数据库死锁。我们认为的解决方案是在运行数据库脚本之前锁定数据库。

我们可以在运行脚本之前锁定数据库访问权限并在运行脚本后解锁它吗?

4

3 回答 3

2

用于测试的共享数据库从来都不是一个好主意,大概您知道这就是为什么您要询问如何一次限制对一个用户的访问。

抛开讲道......我想提供一个liquibase的左字段解决方案来管理数据库模式和数据填充。具有许多有用的功能,其中之一是它会自动锁定数据库并防止两个 liquibase 实例相互干扰。

例子

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.myspotontheweb.db</groupId>
    <artifactId>liquibase-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <!-- Liquibase settings -->
        <liquibase.url>jdbc:h2:target/db1/liquibaseTest;AUTO_SERVER=TRUE</liquibase.url>
        <liquibase.driver>org.h2.Driver</liquibase.driver>
        <liquibase.username>user</liquibase.username>
        <liquibase.password>pass</liquibase.password>
        <liquibase.changeLogFile>com/myspotontheweb/db/changelog/db-changelog-master.xml</liquibase.changeLogFile>
        <liquibase.promptOnNonLocalDatabase>false</liquibase.promptOnNonLocalDatabase>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.162</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-maven-plugin</artifactId>
                <version>2.0.2</version>
                <executions>
                    <execution>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>update</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
于 2012-05-29T18:28:49.447 回答
0

这实际上取决于您如何使用数据库。如果不同的用户是不同的oracle用户,应该没有问题,因为每个用户都可以有自己的表,不应该互相干扰。

如果每个用户都连接到同一个 Oracle 用户,则可能存在冲突。如果每个测试都需要对所有资源的独占访问,您可以构建一个控制表来控制允许访问和不允许访问的人员。这应该在测试准备和测试结束步骤中进行编码才能有效。可以进行简单的插入表并检查“您的”插入是否是第一个。使用 dbms_lock 也是一个类似的选项。

另一种方法是使用 Oracle 资源管理器,并将最大会话限制设置为 1,用于运行独占测试的 Oracle 数据库帐户。这样做,每次连接都会被拒绝,直到测试用户断开连接后连接槽再次可用。

于 2012-05-29T07:23:14.270 回答
0

您可以执行以下操作:

在脚本开始时尝试锁定一个表。

lock table <some_table> in exclusive mode nowait;

只有在没有其他进程锁定此表时,这才会成功。如果失败,另一个进程已经在运行。

如果您获得了锁,请运行脚本的其余部分。请注意,脚本中的任何提交或回滚都会结束锁定,因此只能在脚本的最后提交或回滚。

还要确保锁定一个表,该表的唯一目的是锁定某些东西以便专门运行您的脚本。

于 2012-05-31T06:44:06.450 回答