All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onetwo.dbm.lock.SimpleDBLocker Maven / Gradle / Ivy

The newest version!
package org.onetwo.dbm.lock;
/**
 * @author weishao zeng
 * 
*/ import java.util.Date; import java.util.Optional; import java.util.function.Supplier; import org.apache.commons.lang3.StringUtils; import org.onetwo.common.db.generator.meta.TableMeta; import org.onetwo.common.db.spi.BaseEntityManager; import org.onetwo.common.log.JFishLoggerFactory; import org.onetwo.dbm.core.spi.DbmSessionFactory; import org.onetwo.dbm.exception.DbmException; import org.onetwo.dbm.utils.DbmErrors; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; /*** * 只是简单的基于数据库行锁的分布式锁,不支持重入和超时中断 * * @author way * */ public class SimpleDBLocker { private static final Logger logger = JFishLoggerFactory.getLogger(SimpleDBLocker.class); @Autowired private BaseEntityManager baseEntityManager; private String tableName = "dbm_lock"; public SimpleDBLocker() { } public void setTableName(String tableName) { this.tableName = tableName; } public String getLockTableCreateSql() { return "create table " + tableName + " ( " + " id varchar(32) not null, " + " lock_at datetime, " + " release_at datetime, " + " primary key (id) " + ")"; } @Transactional public void initLocker(String lockerId) { DbmSessionFactory sf = baseEntityManager.getSessionFactory(); Optional tableOpt = sf.getDatabaseMetaDialet().findTableMeta(tableName); if (!tableOpt.isPresent()) { sf.getSession() .createDbmQuery(getLockTableCreateSql()) .executeUpdate(); } LockerEntity locker = baseEntityManager.findById(LockerEntity.class, lockerId); if (locker==null) { locker = new LockerEntity(); locker.setId(lockerId); baseEntityManager.save(locker); } } /*@Transactional public Locker lock(String lockerId) { LockerEntity locker = baseEntityManager.lockWrite(LockerEntity.class, lockerId); if (locker==null) { throw new DbmException(DbmErrors.ERR_LOCK_ID_NOT_FOUND) .put("lockerId", lockerId); } locker.setLockAt(new Date()); Locker lock = new Locker(locker); return lock; }*/ @Transactional public T lock(String lockerId, Supplier supplier) { return lock(null, lockerId, supplier); } @Transactional public T lock(String debugTag, String lockerId, Supplier supplier) { LockerEntity locker = baseEntityManager.lockWrite(LockerEntity.class, lockerId); if (locker==null) { throw new DbmException(DbmErrors.ERR_LOCK_ID_NOT_FOUND) .put("lockerId", lockerId); } locker.setLockAt(new Date()); Locker lock = new Locker(locker, debugTag); try { return supplier.get(); } finally { lock.unlock(); } } /*public T lock(String lockerId, int timeoutInSeconds, Supplier supplier) { try { // 事务超时时间,这个超时是非中断式触发的,这样无法实现中断式超时 return Dbms.doInPropagation(baseEntityManager.getSessionFactory(), TransactionDefinition.PROPAGATION_REQUIRES_NEW, timeoutInSeconds, tx -> { return lock(lockerId, supplier); }); } catch (TransactionTimedOutException e) { throw new DbmException(DbmErrors.ERR_LOCK_TIMEOUT) .put("lockerId", lockerId); } }*/ public class Locker { private String debugTag; private LockerEntity data; public Locker(LockerEntity data, String debugTag) { super(); this.data = data; this.debugTag = debugTag; if (StringUtils.isNotBlank(debugTag)) { logger.info("{} start lock...", debugTag); } } public void unlock() { if (StringUtils.isNotBlank(debugTag)) { logger.info("{} try to unlock...", debugTag); } data.setReleaseAt(new Date()); baseEntityManager.update(data); if (StringUtils.isNotBlank(debugTag)) { logger.info("{} unlocked", debugTag); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy