如何序列化VSTS CI分支构建?解决多分支数据库测试冲突问题
解决Azure DevOps(原VSTS)多分支CI构建数据库测试冲突的并发控制方案
针对你遇到的多分支触发CI时真实数据库测试冲突的问题,我给你几个实用的解决方案,不用换内存数据库就能实现同一时间仅运行一个带数据库测试的构建:
方案一:用单代理池强制串行执行
这是最直接的方式,通过控制代理资源来限制并发:
- 先在Azure DevOps的代理池管理里,创建一个专门的代理池,只添加1个代理实例(如果没有现成的,就配置一个新代理)。
- 编辑你的CI构建定义,找到对应执行单元测试的作业,把它的代理池指定为这个单代理池。
- 这样一来,所有触发的构建都会排队等待这个唯一的代理,同一时间只能有一个构建在跑数据库测试,完全避免冲突。
方案二:给构建定义设置并发限制
如果不想单独搞代理池,直接在构建定义里做限制更简单:
- 打开你的CI构建定义编辑页面,切换到选项标签页。
- 找到并发控制区域,勾选「启用并发限制」,然后把「最大并发数」设为1。
- 这个设置会让该构建定义的所有实例(不管哪个分支触发的)同一时间只能运行一个,其他触发的会自动进入队列等待,直到当前构建完成。
方案三:用SQL Azure应用锁做测试阶段的串行控制
如果只是测试环节需要串行,其他构建步骤(比如编译、打包)想并行的话,可以用数据库本身的锁机制:
- 在单元测试的初始化代码里,添加获取独占锁的逻辑,用SQL Azure的
sp_getapplock存储过程:-- 获取独占锁,超时时间设为5分钟(可根据你的测试时长调整) EXEC sp_getapplock @Resource = 'CI_Test_Db_Global_Lock', @LockMode = 'Exclusive', @LockTimeout = 300000; - 在所有测试执行完成后,记得释放锁:
EXEC sp_releaseapplock @Resource = 'CI_Test_Db_Global_Lock'; - 这样多个构建同时启动时,只有拿到锁的那个能执行测试,其他的会等待锁释放,既保证了测试的串行,又不影响其他步骤的并行。
根据你的实际场景选就行:如果整个构建都需要串行,方案一或二都可以;如果只是测试环节需要,方案三更灵活。
内容的提问来源于stack exchange,提问作者Paul Hatcher
相关产品推荐
相关产品推荐

