I got a solution here in the link below
https://sitecorejunkie.com/2013/09/28/periodically-unlock-items-of-idle-users-in-sitecore/
We can create a task and run after every predefined no of hours. e.g 4 hrs in below example
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <settings> <setting name="UnlockItems.ElapsedTimeWhenIdle" value="00:04:00:00" /> </settings>
Code for UnlockItems class
using System; using Sitecore.Configuration; using Sitecore.Data; using Sitecore.Data.Items; using Sitecore.Diagnostics; using Sitecore.Security.Accounts; using Sitecore.Tasks; using Sitecore.Web.Authentication; namespace Sitecore.Sandbox.Tasks { public class UnlockItems { private static readonly TimeSpan ElapsedTimeWhenIdle = GetElapsedTimeWhenIdle(); public void UnlockIdleUserItems(Item[] items, CommandItem command, ScheduleItem schedule) { if (ElapsedTimeWhenIdle == TimeSpan.Zero) { return; } IEnumerable<Item> lockedItems = GetLockedItems(schedule.Database); foreach (Item lockedItem in lockedItems) { UnlockIfApplicable(lockedItem); } } private static IEnumerable<Item> GetLockedItems(Database database) { Assert.ArgumentNotNull(database, "database"); return database.SelectItems("fast://*[@__lock='%owner=%']"); } private void UnlockIfApplicable(Item item) { Assert.ArgumentNotNull(item, "item"); if (!ShouldUnlockItem(item)) { return; } Unlock(item); } private static bool ShouldUnlockItem(Item item) { Assert.ArgumentNotNull(item, "item"); if(!item.Locking.IsLocked()) { return false; } string owner = item.Locking.GetOwner(); return !IsUserAdmin(owner) && IsUserIdle(owner); } private static bool IsUserAdmin(string username) { Assert.ArgumentNotNullOrEmpty(username, "username"); User user = User.FromName(username, false); Assert.IsNotNull(user, "User must be null due to a wrinkle in the interwebs :-/"); return user.IsAdministrator; } private static bool IsUserIdle(string username) { Assert.ArgumentNotNullOrEmpty(username, "username"); DomainAccessGuard.Session userSession = DomainAccessGuard.Sessions.Find(session => session.UserName == username); if(userSession == null) { return true; } return userSession.LastRequest.Add(ElapsedTimeWhenIdle) <= DateTime.Now; } private void Unlock(Item item) { Assert.ArgumentNotNull(item, "item"); try { string owner = item.Locking.GetOwner(); item.Editing.BeginEdit(); item.Locking.Unlock(); item.Editing.EndEdit(); Log.Info(string.Format("Unlocked {0} - was locked by {1}", item.Paths.Path, owner), this); } catch (Exception ex) { Log.Error(this.ToString(), ex, this); } } private static TimeSpan GetElapsedTimeWhenIdle() { TimeSpan elapsedTimeWhenIdle; if (TimeSpan.TryParse(Settings.GetSetting("UnlockItems.ElapsedTimeWhenIdle"), out elapsedTimeWhenIdle)) { return elapsedTimeWhenIdle; } return TimeSpan.Zero; } }
}