C#调用SharpSvn执行CleanUp报sqlite[S8]只读数据库错误咨询
问题现象
执行如下C#代码时触发异常:
svnclient.CleanUp(WorkDirPath);
完整报错信息:
SharpSvn.SvnException: sqlite[S8]: attempt to write a readonly database ---> SharpSvn.SvnException: Additional errors: ---> SharpSvn.SvnException: sqlite[S8]: attempt to write a readonly database
问题背景
- 开发目标为Visual Studio应用,需要支持终端用户通过应用直接向SVN服务器上传、下载文件
- 服务端环境:Windows服务器安装4.3.3版本VisualSVN Server Manager
- 客户端依赖:最初通过Nuget引入SharpSvn.1.8-x64包实现SVN交互,升级SharpSvn到1.14001.156版本后问题仍存在
- 复现逻辑:调用Add接口添加文件时首先抛出
Failed to lock working copy错误,后续执行CleanUp指令时触发上述SQLite只读报错 - 核心疑问:4.3.3版本的VisualSVN Server是否兼容1.14版本的SharpSvn?
相关业务代码如下:
svnclient.Authentication.DefaultCredentials = new NetworkCredential(_svnuser, _svnpwd); CleanCommand(svnclient,_userworkdir); public bool AddFile(string path, SvnClient svnclient) { try { return svnclient.Add(path); } catch (Exception ex) { Log.Error(String.Format(String.Format("Exception in function AddFile := {0} FilePath :- {1}", ex.Message.ToString(), path))); return false; } } public bool CleanCommand(SvnClient svnclient, String workingdir) { bool res = false; try { res = svnclient.CleanUp(workingdir); } catch (Exception ex) { Log.Error(String.Format(String.Format("Exception in function CleanCommand := {0}, workingdir :- {1}", ex.Message.ToString(), workingdir))); res = false; } return res; }
问题解答
首先明确版本兼容性结论:4.3.3版本VisualSVN Server底层基于Subversion 1.14服务端构建,和1.14版本的SharpSvn完全兼容,该报错和版本兼容性没有关系。
两个报错的核心根因一致:运行应用的进程身份对SVN工作副本目录(即代码中_userworkdir指向的路径)缺少写入权限。SVN工作副本的所有元数据都存储在目录下.svn隐藏文件夹内的SQLite数据库中,执行Add、CleanUp这类写操作时必须修改该数据库,同时需要在目录下生成临时锁文件。一旦进程对目录没有写入权限,就会先触发锁文件创建失败的Failed to lock working copy错误,后续CleanUp操作写入数据库失败就会抛出attempt to write a readonly database异常。
按以下顺序排查修复:
- 校验目录权限
找到_userworkdir对应的本地文件夹,打开「属性-安全」面板,确认运行应用的账号(桌面应用即当前启动程序的登录用户,IIS部署即对应应用程序池的运行身份)对该目录、所有子文件及子文件夹(包含.svn隐藏目录)拥有读取、写入、修改的完整权限。 - 取消目录只读属性
打开工作副本根目录的属性面板,取消勾选「只读」选项,选择将属性变更应用到目录下所有子内容。 - 排除文件占用
检查是否有其他进程(如本地安装的TortoiseSVN客户端、杀毒软件、云同步工具)正在占用.svn目录下的文件,关闭相关进程后重试操作。 - 重建损坏的工作副本
以上操作都无效时说明本地工作副本元数据已经损坏,直接删除原有工作副本,重新执行CheckOut操作拉取全新副本到有权限的本地目录,再执行后续文件操作即可。
内容的提问来源于stack exchange,提问作者Ankush
相关产品推荐
相关产品推荐

