1、有的使用者無法新增,昨天已經提交該問題,需儘快處理,目前有人入職但是無法使用OA

2、有的使用者新增後,出現瞭如下的情況,同一個使用者出現兩條記錄(具體如下圖),造成該使用者無法登陸;但是生成了該員工的檔案,但是檢視詳情時,卻又無法看到資料,都是空檔案;

  這些問題的出現跟最近新上線的功能即新建系統使用者直接建立空檔案功能有關(僅包括工號、使用者名稱、姓名以及自動建立標識)。

  對於問題1,我們直接遠端除錯到生產系統,程式碼如下:

UserEntity userEntity = userService.queryUserByStaffId(staffinfoEntity.getStaffId());
		if (userEntity != null) {
			boolean isOk = userService.updateUserInfoforDefine4(userEntity.getUserCode(), "updateNofiles");
			if(isOk) {
				code = staffinfoDao.add(staffinfoEntity);
			}
			try {
				moduleProxyService.updateUserAndLdapAdByStaffInfo(staffinfoEntity);
			} catch (Exception e) {
				throw new StaffInfoException("新增檔案失敗" + e.getMessage());
			}
		} else {
			code = staffinfoDao.add(staffinfoEntity);
		}

  在第一行查詢時,user只有一個。然後我們進到updateUserAndLdapAdByStaffinfo方法中,該方法第一行即為根據工號查詢使用者。此時系統則報出錯誤。我們使用mybatis的selectOne,但是結果集卻為兩個。我們開始查詢user表發現並不存在對應新增staffid的使用者,因為事務在此處並未提交,這是沒有問題的。但事務並未提交,在前一句還查的是一條,為什麼在這裡就變成了兩條。在這兩句中間只有一句話,那就是插入了一條檔案資料。那就是在事務中檔案及使用者資料都應該是一條。

  我們開啟對應queryUserByStaffId的方法,如下:

<!-- 按員工工號查詢  -->
	<select id="queryUserByStaffId"	resultMap="UserResultMap"  parameterType="String">
		SELECT 
		<include refid="UserAll_column"/>, User.userStatus
		FROM 
		<include refid="User_Staff_View"/> 
		User  
		WHERE User.staffId = #{staffid}
	</select>
	<sql id = "User_Staff_View">
		(SELECT tsu.id,tsu.sortNo,tsu.userCode,tsu.deptCode,tsu.deptName,tsu.userName,tsu.userNamePinying,tsu.sex,tsu.userNameEn,tsu.aliasName,tsu.`password`,tsu.dn,tsu.managementScopeType,tsu.managementScope,
		tsu.accessControl,tsu.createTime,tsu.createUserCode,tsu.bindingIp,tsu.modifyTime,tsu.modifyUserCode,tsu.define1,tsu.define2,tsu.define3,tsu.active,tsu.staffId,tsu.deskMenuSequence,tsu.userStatus,
		tsu.givenName,tsu.sn,tsu.displayname,
		tps.personalEmail AS email,
		tps.phone AS mobile,
		tps.stationNo AS physicalDeliveryOfficeName,
		tps.extensionPhone AS telephoneNumber,
		tps.officeAddress AS l,
		tps.postName AS title,
		tps.directLeaderName AS manager,
		tps.define4 AS define4
 		FROM t_sys_user tsu INNER JOIN t_per_staffinfo tps ON tsu.staffId = tps.staffId)
	</sql>	

  這種查詢使用者的方法源於我們之前的一次優化過程。因為使用者和檔案資訊中存在部分欄位重複,我們將user表中與檔案資訊存在重複的一些欄位進行了整理,統一關聯到檔案表中。因為user表中有一些欄位被刪除,而在業務中可能又需要這些欄位,所以我們加了如User_Staff_View的查詢方式。

  負責的工程師首先認為是inner join導致的這個問題,導致出現兩條。我馬上予以了否認,如果userstaffinfo各只有一條資料,使用inner join不會產生兩條查詢結果。工程師修改為left join得到的結果也是一樣。

  同時,其他的問題不斷爆出,出現了問題2,錯誤原因了也是登陸成功後查詢使用者資訊,因selectOne報出500錯誤。我在系統中查詢同一工號或使用者名稱確實是兩條相同的使用者資訊。於是我問運維同事什麼情況下會插入兩條相同使用者資訊。隨後在後臺資料中我又發現使用者記錄卻只有一條,為什麼查詢卻會出現兩條呢?

  問題逐漸聚焦在查詢方法上。這個關聯查詢出現問題可以肯定的是不是使用者資訊有多條,就是檔案資訊有多個。但從業務角度講,使用者和檔案相對於staffid都是全域性唯一的。我查詢了檔案資料,發現檔案果然就是兩條——HR在使用OA為新入職員工建立檔案使用的是excel匯入的追加功能(匯入有追加和更新兩種,如果選擇追加,則不做判斷,直接插入新記錄),而新上線的功能又會在建立使用者時同步建立一個空檔案,從而產生兩條檔案記錄,也影響到了使用者的查詢。

  再回到第一個問題,我們知道,新增使用者時在新增使用者未完成之前,新增檔案動作還沒有執行。這時候不僅使用者,檔案也只是一條未提交事務記錄,不可能存在多條。我們進一步確認,發現我們新增使用者的那個工號已經在使用者表中存在,這個工號曾經被分配給一個放棄入職的新員工,放棄入職後IT並未將其刪除,所以在新建使用者後,未提交事務中的記錄+已存在的記錄恰是兩條。這個問題的錯誤導向也直接影響了我們對問題2的分析和判斷。

  下面我們看一下inner joinleft join
ight join三者的區別:三者的定義我們大家都知道,inner join只查出符合條件的記錄,left join以左表為基準,right join以右表為基準。我們看看我們這種情況,使用三種join的查詢結果,經過測試,都是兩條。其實這也是我馬上對工程師的判斷予以否認的原因。